From 35585c499f1466037b3788598756e1eb0009f51f Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 28 Feb 2019 22:43:53 +0000 Subject: [PATCH 01/24] Aggregation of drive-by cosmetic changes. --- src/libcore/cell.rs | 2 +- src/libcore/ops/unsize.rs | 2 +- src/librustc/hir/intravisit.rs | 1 - src/librustc/hir/lowering.rs | 125 +++++++++--------- src/librustc/hir/map/collector.rs | 6 +- src/librustc/hir/map/definitions.rs | 8 +- src/librustc/hir/map/mod.rs | 73 +++++----- src/librustc/hir/mod.rs | 36 +++-- src/librustc/hir/print.rs | 4 +- src/librustc/ich/impls_hir.rs | 2 +- src/librustc/infer/mod.rs | 7 +- src/librustc/infer/opaque_types/mod.rs | 25 ++-- src/librustc/middle/resolve_lifetime.rs | 4 +- src/librustc/middle/stability.rs | 4 +- src/librustc/mir/interpret/error.rs | 7 +- src/librustc/traits/error_reporting.rs | 6 +- src/librustc/traits/select.rs | 28 ++-- src/librustc/traits/structural_impls.rs | 8 +- src/librustc/ty/context.rs | 14 +- src/librustc/ty/mod.rs | 24 ++-- src/librustc/ty/query/plumbing.rs | 22 +-- src/librustc/ty/util.rs | 2 +- src/librustc/util/common.rs | 48 +++---- src/librustc_borrowck/dataflow.rs | 19 ++- src/librustc_codegen_llvm/intrinsic.rs | 4 +- src/librustc_codegen_ssa/back/link.rs | 8 +- src/librustc_codegen_ssa/mir/block.rs | 22 +-- src/librustc_codegen_ssa/mir/place.rs | 45 ++++--- src/librustc_lint/builtin.rs | 15 +-- .../nll/region_infer/error_reporting/mod.rs | 4 +- src/librustc_mir/build/mod.rs | 6 +- src/librustc_mir/monomorphize/partitioning.rs | 55 ++++---- src/librustc_passes/ast_validation.rs | 35 ++--- src/librustc_resolve/lib.rs | 16 ++- src/librustc_typeck/astconv.rs | 54 ++++---- src/librustc_typeck/check/coercion.rs | 2 +- src/librustc_typeck/check/mod.rs | 8 +- src/librustc_typeck/check/writeback.rs | 29 ++-- src/librustc_typeck/collect.rs | 51 +++---- src/librustc_typeck/lib.rs | 8 +- src/librustdoc/clean/mod.rs | 20 +-- src/librustdoc/html/format.rs | 7 +- src/libstd/panicking.rs | 5 +- src/libstd/sys_common/backtrace.rs | 2 +- src/libsyntax/ast.rs | 4 +- src/libsyntax/ext/build.rs | 33 +++-- src/libsyntax/parse/parser.rs | 58 ++++---- src/libsyntax/print/pprust.rs | 8 +- src/libsyntax/ptr.rs | 3 +- src/libsyntax/visit.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 3 +- src/libsyntax_ext/proc_macro_decls.rs | 7 +- .../pprust-expr-roundtrip.rs | 32 +++-- .../traits/trait-object-auto-dedup.rs | 9 +- .../no_revealing_outside_defining_module.rs | 2 +- src/test/ui/type/type-alias-bounds.rs | 36 ++--- src/test/ui/type/type-alias-bounds.stderr | 22 ++- 57 files changed, 550 insertions(+), 542 deletions(-) diff --git a/src/libcore/cell.rs b/src/libcore/cell.rs index 9d26ecbacdcbb..239ff017cc230 100644 --- a/src/libcore/cell.rs +++ b/src/libcore/cell.rs @@ -1351,7 +1351,7 @@ impl<'b> BorrowRefMut<'b> { } } - // Clone a `BorrowRefMut`. + // Clones a `BorrowRefMut`. // // This is only valid if each `BorrowRefMut` is used to track a mutable // reference to a distinct, nonoverlapping range of the original object. diff --git a/src/libcore/ops/unsize.rs b/src/libcore/ops/unsize.rs index 7f81481ab5b1d..8e46830084642 100644 --- a/src/libcore/ops/unsize.rs +++ b/src/libcore/ops/unsize.rs @@ -71,7 +71,7 @@ impl, U: ?Sized> CoerceUnsized<*const U> for *const T {} /// This is used for object safety, to check that a method's receiver type can be dispatched on. /// -/// example impl: +/// An example implementation of the trait: /// /// ``` /// # #![feature(dispatch_from_dyn, unsize)] diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 9cf365addca9b..f838ec84d8b31 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -934,7 +934,6 @@ pub fn walk_impl_item_ref<'v, V: Visitor<'v>>(visitor: &mut V, impl_item_ref: &' visitor.visit_defaultness(defaultness); } - pub fn walk_struct_def<'v, V: Visitor<'v>>(visitor: &mut V, struct_definition: &'v VariantData) { if let Some(ctor_hir_id) = struct_definition.ctor_hir_id() { visitor.visit_id(ctor_hir_id); diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 14a6e93341e32..af8c9c38de5ff 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -17,7 +17,7 @@ //! 'folding' an existing one), then you create a new ID using `next_id()`. //! //! You must ensure that IDs are unique. That means that you should only use the -//! ID from an AST node in a single HIR node (you can assume that AST node IDs +//! ID from an AST node in a single HIR node (you can assume that AST node-IDs //! are unique). Every new node must have a unique ID. Avoid cloning HIR nodes. //! If you do, you must then set the new node's ID to a fresh one. //! @@ -175,6 +175,8 @@ pub trait Resolver { ) -> hir::Path; } +/// Context of `impl Trait` in code, which determines whether it is allowed in an HIR subtree, +/// and if so, what meaning it has. #[derive(Debug)] enum ImplTraitContext<'a> { /// Treat `impl Trait` as shorthand for a new universal generic parameter. @@ -670,14 +672,14 @@ impl<'a> LoweringContext<'a> { fn insert_item(&mut self, item: hir::Item) { let id = item.hir_id; - // FIXME: Use debug_asset-rt + // FIXME: Use `debug_asset-rt`. assert_eq!(id.local_id, hir::ItemLocalId::from_u32(0)); self.items.insert(id, item); self.modules.get_mut(&self.current_module).unwrap().items.insert(id); } fn allocate_hir_id_counter(&mut self, owner: NodeId) -> hir::HirId { - // Setup the counter if needed + // Set up the counter if needed. self.item_local_id_counters.entry(owner).or_insert(0); // Always allocate the first `HirId` for the owner itself. let lowered = self.lower_node_id_with_owner(owner, owner); @@ -718,7 +720,7 @@ impl<'a> LoweringContext<'a> { { let counter = self.item_local_id_counters .insert(owner, HIR_ID_COUNTER_LOCKED) - .unwrap_or_else(|| panic!("No item_local_id_counters entry for {:?}", owner)); + .unwrap_or_else(|| panic!("no `item_local_id_counters` entry for {:?}", owner)); let def_index = self.resolver.definitions().opt_def_index(owner).unwrap(); self.current_hir_id_owner.push((def_index, counter)); let ret = f(self); @@ -758,7 +760,7 @@ impl<'a> LoweringContext<'a> { let local_id_counter = this .item_local_id_counters .get_mut(&owner) - .expect("called lower_node_id_with_owner before allocate_hir_id_counter"); + .expect("called `lower_node_id_with_owner` before `allocate_hir_id_counter`"); let local_id = *local_id_counter; // We want to be sure not to modify the counter in the map while it @@ -771,7 +773,7 @@ impl<'a> LoweringContext<'a> { .resolver .definitions() .opt_def_index(owner) - .expect("You forgot to call `create_def_with_parent` or are lowering node ids \ + .expect("you forgot to call `create_def_with_parent` or are lowering node-IDs \ that do not belong to the current owner"); hir::HirId { @@ -863,7 +865,7 @@ impl<'a> LoweringContext<'a> { result } - /// Creates a new hir::GenericParam for every new lifetime and + /// Creates a new `hir::GenericParam` for every new lifetime and /// type parameter encountered while evaluating `f`. Definitions /// are created with the parent provided. If no `parent_id` is /// provided, no definitions will be returned. @@ -1197,7 +1199,7 @@ impl<'a> LoweringContext<'a> { assert_eq!( len + 1, self.loop_scopes.len(), - "Loop scopes should be added and removed in stack order" + "loop scopes should be added and removed in stack order" ); self.loop_scopes.pop().unwrap(); @@ -1351,9 +1353,9 @@ impl<'a> LoweringContext<'a> { } fn lower_generic_arg(&mut self, - arg: &ast::GenericArg, - itctx: ImplTraitContext<'_>) - -> hir::GenericArg { + arg: &ast::GenericArg, + itctx: ImplTraitContext<'_>) + -> hir::GenericArg { match arg { ast::GenericArg::Lifetime(lt) => GenericArg::Lifetime(self.lower_lifetime(<)), ast::GenericArg::Type(ty) => GenericArg::Type(self.lower_ty_direct(&ty, itctx)), @@ -1537,7 +1539,7 @@ impl<'a> LoweringContext<'a> { } } } - TyKind::Mac(_) => panic!("TyMac should have been expanded by now."), + TyKind::Mac(_) => bug!("`TyMac` should have been expanded by now."), TyKind::CVarArgs => { // Create the implicit lifetime of the "spoofed" `VaList`. let span = self.sess.source_map().next_point(t.span.shrink_to_lo()); @@ -1563,7 +1565,7 @@ impl<'a> LoweringContext<'a> { // Make sure we know that some funky desugaring has been going on here. // This is a first: there is code in other places like for loop // desugaring that explicitly states that we don't want to track that. - // Not tracking it makes lints in rustc and clippy very fragile as + // Not tracking it makes lints in rustc and clippy very fragile, as // frequently opened issues show. let exist_ty_span = self.mark_span_with_reason( CompilerDesugaringKind::ExistentialReturnType, @@ -1650,7 +1652,7 @@ impl<'a> LoweringContext<'a> { parent_index: DefIndex, bounds: &hir::GenericBounds, ) -> (HirVec, HirVec) { - // This visitor walks over impl trait bounds and creates defs for all lifetimes which + // This visitor walks over `impl Trait` bounds and creates defs for all lifetimes that // appear in the bounds, excluding lifetimes that are created within the bounds. // E.g., `'a`, `'b`, but not `'c` in `impl for<'c> SomeTrait<'a, 'b, 'c>`. struct ImplTraitLifetimeCollector<'r, 'a: 'r> { @@ -1758,8 +1760,7 @@ impl<'a> LoweringContext<'a> { def_node_id, DefPathData::LifetimeNs(name.ident().as_interned_str()), Mark::root(), - lifetime.span, - ); + lifetime.span); let (name, kind) = match name { hir::LifetimeName::Underscore => ( @@ -1770,7 +1771,7 @@ impl<'a> LoweringContext<'a> { param_name, hir::LifetimeParamKind::Explicit, ), - _ => bug!("expected LifetimeName::Param or ParamName::Plain"), + _ => bug!("expected `LifetimeName::Param` or `ParamName::Plain`"), }; self.output_lifetime_params.push(hir::GenericParam { @@ -1915,7 +1916,7 @@ impl<'a> LoweringContext<'a> { { ParenthesizedGenericArgs::Err } - // A warning for now, for compatibility reasons + // A warning for now, for compatibility reasons. _ => ParenthesizedGenericArgs::Warn, }; @@ -2079,11 +2080,14 @@ impl<'a> LoweringContext<'a> { } }; err.emit(); - (self.lower_angle_bracketed_parameter_data( - &data.as_angle_bracketed_args(), - param_mode, - itctx).0, - false) + ( + self.lower_angle_bracketed_parameter_data( + &data.as_angle_bracketed_args(), + param_mode, + itctx + ).0, + false, + ) } }, } @@ -2109,11 +2113,11 @@ impl<'a> LoweringContext<'a> { let no_ty_args = generic_args.args.len() == expected_lifetimes; let no_bindings = generic_args.bindings.is_empty(); let (incl_angl_brckt, insertion_span, suggestion) = if no_ty_args && no_bindings { - // If there are no (non-implicit) generic args or associated-type + // If there are no (non-implicit) generic args or associated type // bindings, our suggestion includes the angle brackets. (true, path_span.shrink_to_hi(), format!("<{}>", anon_lt_suggestion)) } else { - // Otherwise—sorry, this is kind of gross—we need to infer the + // Otherwise (sorry, this is kind of gross) we need to infer the // place to splice in the `'_, ` from the generics that do exist. let first_generic_span = first_generic_span .expect("already checked that type args or bindings exist"); @@ -2196,19 +2200,21 @@ impl<'a> LoweringContext<'a> { ast::GenericArg::Type(_) => true, _ => false, }); - (hir::GenericArgs { - args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(), - bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx.reborrow())).collect(), - parenthesized: false, - }, - !has_types && param_mode == ParamMode::Optional) + ( + hir::GenericArgs { + args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(), + bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx.reborrow())).collect(), + parenthesized: false, + }, + !has_types && param_mode == ParamMode::Optional + ) } fn lower_parenthesized_parameter_data( &mut self, data: &ParenthesizedArgs, ) -> (hir::GenericArgs, bool) { - // Switch to `PassThrough` mode for anonymous lifetimes: this + // Switch to `PassThrough` mode for anonymous lifetimes; this // means that we permit things like `&Ref`, where `Ref` has // a hidden lifetime parameter. This is needed for backwards // compatibility, even in contexts like an impl header where @@ -2300,16 +2306,16 @@ impl<'a> LoweringContext<'a> { // Lowers a function declaration. // - // decl: the unlowered (ast) function declaration. - // fn_def_id: if `Some`, impl Trait arguments are lowered into generic parameters on the + // `decl`: the unlowered (AST) function declaration. + // `fn_def_id`: if `Some`, impl Trait arguments are lowered into generic parameters on the // given DefId, otherwise impl Trait is disallowed. Must be `Some` if - // make_ret_async is also `Some`. - // impl_trait_return_allow: determines whether impl Trait can be used in return position. - // This guards against trait declarations and implementations where impl Trait is + // `make_ret_async` is also `Some`. + // `impl_trait_return_allow`: determines whether `impl Trait` can be used in return position. + // This guards against trait declarations and implementations where `impl Trait` is // disallowed. - // make_ret_async: if `Some`, converts `-> T` into `-> impl Future` in the - // return type. This is used for `async fn` declarations. The `NodeId` is the id of the - // return type impl Trait item. + // `make_ret_async`: if `Some`, converts `-> T` into `-> impl Future` in the + // return type. This is used for `async fn` declarations. The `NodeId` is the ID of the + // return type `impl Trait` item. fn lower_fn_decl( &mut self, decl: &FnDecl, @@ -2350,7 +2356,7 @@ impl<'a> LoweringContext<'a> { ); self.lower_async_fn_ret_ty( &decl.output, - in_band_ty_params.expect("make_ret_async but no fn_def_id").0, + in_band_ty_params.expect("`make_ret_async` but no `fn_def_id`").0, ret_id, lt_replacement, ) @@ -2401,16 +2407,16 @@ impl<'a> LoweringContext<'a> { }) } - // Transform `-> T` for `async fn` into -> ExistTy { .. } + // Transforms `-> T` for `async fn` into `-> ExistTy { .. }` // combined with the following definition of `ExistTy`: // - // existential type ExistTy: Future; + // existential type ExistTy: Future; // - // inputs: lowered types of arguments to the function. Used to collect lifetimes. - // output: unlowered output type (`T` in `-> T`) - // fn_def_id: DefId of the parent function. Used to create child impl trait definition. - // exist_ty_node_id: NodeId of the existential type that should be created. - // elided_lt_replacement: replacement for elided lifetimes in the return type + // `inputs`: lowered types of arguments to the function (used to collect lifetimes) + // `output`: unlowered output type (`T` in `-> T`) + // `fn_def_id`: `DefId` of the parent function (used to create child impl trait definition) + // `exist_ty_node_id`: `NodeId` of the existential type that should be created + // `elided_lt_replacement`: replacement for elided lifetimes in the return type fn lower_async_fn_ret_ty( &mut self, output: &FunctionRetTy, @@ -2511,7 +2517,7 @@ impl<'a> LoweringContext<'a> { })) } - /// Turns `-> T` into `Future` + /// Transforms `-> T` into `Future` fn lower_async_fn_output_type_to_future_bound( &mut self, output: &FunctionRetTy, @@ -2757,9 +2763,9 @@ impl<'a> LoweringContext<'a> { -> hir::Generics { // Collect `?Trait` bounds in where clause and move them to parameter definitions. - // FIXME: this could probably be done with less rightward drift. Also looks like two control - // paths where report_error is called are also the only paths that advance to after - // the match statement, so the error reporting could probably just be moved there. + // FIXME: this could probably be done with less rightward drift. It also looks like two + // control paths where `report_error` is called are the only paths that advance to after the + // match statement, so the error reporting could probably just be moved there. let mut add_bounds: NodeMap> = Default::default(); for pred in &generics.where_clause.predicates { if let WherePredicate::BoundPredicate(ref bound_pred) = *pred { @@ -2952,7 +2958,7 @@ impl<'a> LoweringContext<'a> { hir_id: self.lower_node_id(f.id), ident: match f.ident { Some(ident) => ident, - // FIXME(jseyfried): positional field hygiene + // FIXME(jseyfried): positional field hygiene. None => Ident::new(sym::integer(index), f.span), }, vis: self.lower_visibility(&f.vis, None), @@ -2979,7 +2985,7 @@ impl<'a> LoweringContext<'a> { } fn lower_param_bounds(&mut self, bounds: &[GenericBound], mut itctx: ImplTraitContext<'_>) - -> hir::GenericBounds { + -> hir::GenericBounds { bounds.iter().map(|bound| self.lower_param_bound(bound, itctx.reborrow())).collect() } @@ -3157,7 +3163,7 @@ impl<'a> LoweringContext<'a> { match *i { ItemKind::ExternCrate(orig_name) => hir::ItemKind::ExternCrate(orig_name), ItemKind::Use(ref use_tree) => { - // Start with an empty prefix + // Start with an empty prefix. let prefix = Path { segments: vec![], span: use_tree.span, @@ -3345,7 +3351,8 @@ impl<'a> LoweringContext<'a> { self.lower_generics(generics, ImplTraitContext::disallowed()), self.lower_param_bounds(bounds, ImplTraitContext::disallowed()), ), - ItemKind::MacroDef(..) | ItemKind::Mac(..) => panic!("Shouldn't still be around"), + ItemKind::MacroDef(..) + | ItemKind::Mac(..) => bug!("`TyMac` should have been expanded by now"), } // [1] `defaultness.has_value()` is never called for an `impl`, always `true` in order to @@ -3632,7 +3639,7 @@ impl<'a> LoweringContext<'a> { .map(|x| self.lower_ty(x, ImplTraitContext::disallowed())), ), ), - TraitItemKind::Macro(..) => panic!("Shouldn't exist any more"), + TraitItemKind::Macro(..) => bug!("macro item shouldn't exist at this point"), }; hir::TraitItem { @@ -3707,7 +3714,7 @@ impl<'a> LoweringContext<'a> { self.lower_param_bounds(bounds, ImplTraitContext::disallowed()), ), ), - ImplItemKind::Macro(..) => panic!("Shouldn't exist any more"), + ImplItemKind::Macro(..) => bug!("`TyMac` should have been expanded by now"), }; hir::ImplItem { @@ -5347,7 +5354,7 @@ impl<'a> LoweringContext<'a> { }) } - /// Given suffix ["b","c","d"], returns path `::std::b::c::d` when + /// Given a suffix `["b", "c", "d"]`, returns path `::std::b::c::d` when /// `fld.cx.use_std`, and `::core::b::c::d` otherwise. /// The path is also resolved according to `is_value`. fn std_path( diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index b5203f9ec1f72..e66fa13f4fca2 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -19,7 +19,7 @@ use std::iter::repeat; use crate::ich::StableHashingContext; use rustc_data_structures::stable_hasher::{HashStable, StableHasher, StableHasherResult}; -/// A Visitor that walks over the HIR and collects Nodes into a HIR map +/// A visitor that walks over the HIR and collects `Node`s into a HIR map. pub(super) struct NodeCollector<'a, 'hir> { /// The crate krate: &'hir Crate, @@ -45,7 +45,7 @@ pub(super) struct NodeCollector<'a, 'hir> { hcx: StableHashingContext<'a>, - // We are collecting DepNode::HirBody hashes here so we can compute the + // We are collecting `DepNode::HirBody` hashes here so we can compute the // crate hash from then later on. hir_body_nodes: Vec<(DefPathHash, Fingerprint)>, } @@ -109,7 +109,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { let mut hir_body_nodes = Vec::new(); - // Allocate DepNodes for the root module + // Allocate `DepNode`s for the root module. let (root_mod_sig_dep_index, root_mod_full_dep_index) = { let Crate { ref module, diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 2324c3f04284f..b85f6f6ce8483 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -239,7 +239,7 @@ impl DefPath { "{}[{}]", component.data.as_interned_str(), component.disambiguator) - .unwrap(); + .unwrap(); } } @@ -263,7 +263,7 @@ impl DefPath { "{}[{}]", component.data.as_interned_str(), component.disambiguator) - .unwrap(); + .unwrap(); } } s @@ -442,7 +442,7 @@ impl Definitions { root_index } - /// Add a definition with a parent definition. + /// Adds a definition with a parent definition. pub fn create_def_with_parent(&mut self, parent: DefIndex, node_id: ast::NodeId, @@ -559,7 +559,7 @@ impl DefPathData { GlobalMetaData(name) => { return name } - // note that this does not show up in user printouts + // Note that this does not show up in user print-outs. CrateRoot => sym::double_braced_crate, Impl => sym::double_braced_impl, Misc => sym::double_braced_misc, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 75799a1903174..18c596f164dc2 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -1,7 +1,8 @@ use self::collector::NodeCollector; pub use self::def_collector::{DefCollector, MacroInvocationData}; -pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, - DisambiguatedDefPathData, DefPathHash}; +pub use self::definitions::{ + Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData, DefPathHash +}; use crate::dep_graph::{DepGraph, DepNode, DepKind, DepNodeIndex}; @@ -238,7 +239,7 @@ impl<'hir> Map<'hir> { }) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. #[inline] pub fn local_def_id_from_hir_id(&self, hir_id: HirId) -> DefId { self.opt_local_def_id_from_hir_id(hir_id).unwrap_or_else(|| { @@ -247,7 +248,7 @@ impl<'hir> Map<'hir> { }) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. #[inline] pub fn opt_local_def_id_from_hir_id(&self, hir_id: HirId) -> Option { let node_id = self.hir_to_node_id(hir_id); @@ -264,7 +265,7 @@ impl<'hir> Map<'hir> { self.definitions.as_local_node_id(def_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. #[inline] pub fn as_local_hir_id(&self, def_id: DefId) -> Option { self.definitions.as_local_hir_id(def_id) @@ -426,7 +427,7 @@ impl<'hir> Map<'hir> { self.fn_decl_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn fn_decl_by_hir_id(&self, hir_id: HirId) -> Option { if let Some(entry) = self.find_entry(hir_id) { entry.fn_decl().cloned() @@ -455,7 +456,7 @@ impl<'hir> Map<'hir> { self.maybe_body_owned_by_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn maybe_body_owned_by_by_hir_id(&self, hir_id: HirId) -> Option { if let Some(entry) = self.find_entry(hir_id) { if self.dep_graph.is_fully_enabled() { @@ -483,7 +484,7 @@ impl<'hir> Map<'hir> { self.body_owner_kind_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn body_owner_kind_by_hir_id(&self, id: HirId) -> BodyOwnerKind { match self.get_by_hir_id(id) { Node::Item(&Item { node: ItemKind::Const(..), .. }) | @@ -587,14 +588,13 @@ impl<'hir> Map<'hir> { } } - /// Retrieve the Node corresponding to `id`, panicking if it cannot - /// be found. + /// Retrieves the `Node` corresponding to `id`, panicking if it cannot be found. pub fn get(&self, id: NodeId) -> Node<'hir> { let hir_id = self.node_to_hir_id(id); self.get_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn get_by_hir_id(&self, id: HirId) -> Node<'hir> { // read recorded by `find` self.find_by_hir_id(id).unwrap_or_else(|| @@ -634,7 +634,7 @@ impl<'hir> Map<'hir> { self.find_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn find_by_hir_id(&self, hir_id: HirId) -> Option> { let result = self.find_entry(hir_id).and_then(|entry| { if let Node::Crate = entry.node { @@ -665,7 +665,7 @@ impl<'hir> Map<'hir> { self.hir_to_node_id(parent_hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn get_parent_node_by_hir_id(&self, hir_id: HirId) -> HirId { if self.dep_graph.is_fully_enabled() { let hir_id_owner = hir_id.owner; @@ -721,24 +721,24 @@ impl<'hir> Map<'hir> { { let mut id = start_id; loop { - let parent_node = self.get_parent_node_by_hir_id(id); - if parent_node == CRATE_HIR_ID { + let parent_id = self.get_parent_node_by_hir_id(id); + if parent_id == CRATE_HIR_ID { return Ok(CRATE_HIR_ID); } - if parent_node == id { + if parent_id == id { return Err(id); } - if let Some(entry) = self.find_entry(parent_node) { + 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_node); + return Ok(parent_id); } else if bail_early(&entry.node) { - return Err(parent_node); + return Err(parent_id); } - id = parent_node; + id = parent_id; } else { return Err(id); } @@ -803,7 +803,7 @@ impl<'hir> Map<'hir> { self.hir_to_node_id(parent_hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn get_parent_item(&self, hir_id: HirId) -> HirId { match self.walk_parent_nodes(hir_id, |node| match *node { Node::Item(_) | @@ -824,7 +824,7 @@ impl<'hir> Map<'hir> { self.get_module_parent_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn get_module_parent_by_hir_id(&self, id: HirId) -> DefId { self.local_def_id_from_hir_id(self.get_module_parent_node(id)) } @@ -861,7 +861,7 @@ impl<'hir> Map<'hir> { self.get_parent_did_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn get_parent_did_by_hir_id(&self, id: HirId) -> DefId { self.local_def_id_from_hir_id(self.get_parent_item(id)) } @@ -871,7 +871,7 @@ impl<'hir> Map<'hir> { self.get_foreign_abi_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn get_foreign_abi_by_hir_id(&self, hir_id: HirId) -> Abi { let parent = self.get_parent_item(hir_id); if let Some(entry) = self.find_entry(parent) { @@ -890,7 +890,7 @@ impl<'hir> Map<'hir> { self.expect_item_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn expect_item_by_hir_id(&self, id: HirId) -> &'hir Item { match self.find_by_hir_id(id) { // read recorded by `find` Some(Node::Item(item)) => item, @@ -946,7 +946,7 @@ impl<'hir> Map<'hir> { self.expect_expr_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn expect_expr_by_hir_id(&self, id: HirId) -> &'hir Expr { match self.find_by_hir_id(id) { // read recorded by find Some(Node::Expr(expr)) => expr, @@ -960,7 +960,7 @@ impl<'hir> Map<'hir> { self.name_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn name_by_hir_id(&self, id: HirId) -> Name { match self.get_by_hir_id(id) { Node::Item(i) => i.ident.name, @@ -977,14 +977,14 @@ impl<'hir> Map<'hir> { } } - /// Given a node ID, get a list of attributes associated with the AST - /// corresponding to the Node ID + /// Given a node ID, gets a list of attributes associated with the AST + /// corresponding to the node-ID. pub fn attrs(&self, id: NodeId) -> &'hir [ast::Attribute] { let hir_id = self.node_to_hir_id(id); self.attrs_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn attrs_by_hir_id(&self, id: HirId) -> &'hir [ast::Attribute] { self.read(id); // reveals attributes on the node let attrs = match self.find_entry(id).map(|entry| entry.node) { @@ -1053,7 +1053,7 @@ impl<'hir> Map<'hir> { self.span_by_hir_id(hir_id) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn span_by_hir_id(&self, hir_id: HirId) -> Span { self.read(hir_id); // reveals span from node match self.find_entry(hir_id).map(|entry| entry.node) { @@ -1101,7 +1101,7 @@ impl<'hir> Map<'hir> { hir_id_to_string(self, self.node_to_hir_id(id), true) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn hir_to_string(&self, id: HirId) -> String { hir_id_to_string(self, id, true) } @@ -1110,7 +1110,7 @@ impl<'hir> Map<'hir> { hir_id_to_string(self, self.node_to_hir_id(id), false) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn hir_to_user_string(&self, id: HirId) -> String { hir_id_to_string(self, id, false) } @@ -1119,7 +1119,7 @@ impl<'hir> Map<'hir> { print::to_string(self, |s| s.print_node(self.get(id))) } - // FIXME(@ljedrz): replace the NodeId variant + // FIXME(@ljedrz): replace the `NodeId` variant. pub fn hir_to_pretty_string(&self, id: HirId) -> String { print::to_string(self, |s| s.print_node(self.get_by_hir_id(id))) } @@ -1451,8 +1451,9 @@ pub fn provide(providers: &mut Providers<'_>) { if let Some(node_id) = tcx.hir().as_local_node_id(def_id) { tcx.hir().def_kind(node_id) } else { - bug!("Calling local def_kind query provider for upstream DefId: {:?}", - def_id) + bug!("calling local def_kind query provider for upstream DefId: {:?}", + def_id + ); } }; } diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 65fc56f2c4878..e29998db7778f 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1,4 +1,4 @@ -// HIR datatypes. See the [rustc guide] for more info. +//! HIR datatypes. See the [rustc guide] for more info. //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/hir.html @@ -121,13 +121,13 @@ impl fmt::Display for HirId { } } -// hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module +// Hack to ensure that we don't try to access the private parts of `ItemLocalId` in this module mod item_local_id_inner { use rustc_data_structures::indexed_vec::Idx; use rustc_macros::HashStable; newtype_index! { - /// An `ItemLocalId` uniquely identifies something within a given "item-like", - /// that is, within a hir::Item, hir::TraitItem, or hir::ImplItem. There is no + /// An `ItemLocalId` uniquely identifies something within a given "item-like"; + /// that is, within a `hir::Item`, `hir::TraitItem`, or `hir::ImplItem`. There is no /// guarantee that the numerical value of a given `ItemLocalId` corresponds to /// the node's position within the owning item in any way, but there is a /// guarantee that the `LocalItemId`s within an owner occupy a dense range of @@ -568,7 +568,6 @@ pub struct GenericParam { pub bounds: GenericBounds, pub span: Span, pub pure_wrt_drop: bool, - pub kind: GenericParamKind, } @@ -1566,13 +1565,13 @@ pub enum ExprKind { /// A struct or struct-like variant literal expression. /// - /// For example, `Foo {x: 1, y: 2}`, or - /// `Foo {x: 1, .. base}`, where `base` is the `Option`. + /// E.g., `Foo {x: 1, y: 2}`, or `Foo {x: 1, .. base}`, + /// where `base` is the `Option`. Struct(P, HirVec, Option>), /// An array literal constructed from one repeated element. /// - /// For example, `[1; 5]`. The first expression is the element + /// E.g., `[1; 5]`. The first expression is the element /// to be repeated; the second is the number of times to repeat it. Repeat(P, AnonConst), @@ -1583,7 +1582,7 @@ pub enum ExprKind { Err, } -/// Optionally `Self`-qualified value/type path or associated extension. +/// Represents an optionally `Self`-qualified value/type path or associated extension. #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum QPath { /// Path to a definition, optionally "fully-qualified" with a `Self` @@ -1738,7 +1737,7 @@ pub struct TraitItem { pub span: Span, } -/// A trait method's body (or just argument names). +/// Represents a trait method's body (or just argument names). #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum TraitMethod { /// No default body in the trait, just a signature. @@ -1751,13 +1750,12 @@ pub enum TraitMethod { /// Represents a trait method or associated constant or type #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum TraitItemKind { - /// An associated constant with an optional value (otherwise `impl`s - /// must contain a value) + /// An associated constant with an optional value (otherwise `impl`s must contain a value). Const(P, Option), - /// A method with an optional body + /// A method with an optional body. Method(MethodSig, TraitMethod), /// An associated type with (possibly empty) bounds and optional concrete - /// type + /// type. Type(GenericBounds, Option>), } @@ -1808,9 +1806,9 @@ pub struct TypeBinding { #[derive(Clone, RustcEncodable, RustcDecodable)] pub struct Ty { + pub hir_id: HirId, pub node: TyKind, pub span: Span, - pub hir_id: HirId, } impl fmt::Debug for Ty { @@ -1874,7 +1872,7 @@ pub enum TyKind { BareFn(P), /// The never type (`!`). Never, - /// A tuple (`(A, B, C, D,...)`). + /// A tuple (`(A, B, C, D, ...)`). Tup(HirVec), /// A path to a type definition (`module::module::...::Type`), or an /// associated type (e.g., ` as Trait>::Type` or `::Target`). @@ -2598,7 +2596,7 @@ impl CodegenFnAttrs { } } - /// True if it looks like this symbol needs to be exported, for example: + /// Returns `true` if it looks like this symbol needs to be exported, for example: /// /// * `#[no_mangle]` is present /// * `#[export_name(...)]` is present @@ -2607,8 +2605,8 @@ impl CodegenFnAttrs { self.flags.contains(CodegenFnAttrFlags::NO_MANGLE) || self.export_name.is_some() || match self.linkage { - // these are private, make sure we don't try to consider - // them external + // These are private, so make sure we don't try to consider + // them external. None | Some(Linkage::Internal) | Some(Linkage::Private) => false, diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index c5337381a3d4f..709a43c4734c1 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -1679,8 +1679,8 @@ impl<'a> State<'a> { })?; } - // FIXME(eddyb) This would leak into error messages, e.g.: - // "non-exhaustive patterns: `Some::<..>(_)` not covered". + // FIXME(eddyb): this would leak into error messages (e.g., + // "non-exhaustive patterns: `Some::<..>(_)` not covered"). if infer_types && false { start_or_comma(self)?; self.s.word("..")?; diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index 5b2a1e783c039..f2f909b6af156 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -286,7 +286,7 @@ impl<'a> HashStable> for hir::Mod { inner_span.hash_stable(hcx, hasher); - // Combining the DefPathHashes directly is faster than feeding them + // Combining the `DefPathHash`s directly is faster than feeding them // into the hasher. Because we use a commutative combine, we also don't // have to sort the array. let item_ids_hash = item_ids diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 4414e677fb5b7..e9c47002278df 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -914,10 +914,9 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // variable, and because type variable's can't (at present, at // least) capture any of the things bound by this binder. // - // Really, there is no *particular* reason to do this - // `shallow_resolve` here except as a - // micro-optimization. Naturally I could not - // resist. -nmatsakis + // NOTE(nmatsakis): really, there is no *particular* reason to do this + // `shallow_resolve` here except as a micro-optimization. + // Naturally I could not resist. let two_unbound_type_vars = { let a = self.shallow_resolve(predicate.skip_binder().a); let b = self.shallow_resolve(predicate.skip_binder().b); diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 220b7b5fa67fe..1423b855745e7 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -858,7 +858,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { def_id, substs ); - // Use the same type variable if the exact same Opaque appears more + // Use the same type variable if the exact same opaque type appears more // than once in the return type (e.g., if it's passed to a type alias). if let Some(opaque_defn) = self.opaque_types.get(&def_id) { return opaque_defn.concrete_ty; @@ -880,9 +880,9 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { required_region_bounds ); - // make sure that we are in fact defining the *entire* type - // e.g., `existential type Foo: Bar;` needs to be - // defined by a function like `fn foo() -> Foo`. + // Make sure that we are in fact defining the *entire* type + // (e.g., `existential type Foo: Bar;` needs to be + // defined by a function like `fn foo() -> Foo`). debug!( "instantiate_opaque_types: param_env: {:#?}", self.param_env, @@ -945,18 +945,15 @@ pub fn may_define_existential_type( def_id: DefId, opaque_hir_id: hir::HirId, ) -> bool { - let mut hir_id = tcx - .hir() - .as_local_hir_id(def_id) - .unwrap(); - // named existential types can be defined by any siblings or - // children of siblings + let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + // Named existential types can be defined by any siblings or + // children of siblings. let mod_id = tcx.hir().get_parent_item(opaque_hir_id); - // so we walk up the node tree until we hit the root or the parent - // of the opaque type - while hir_id != mod_id && hir_id != hir::CRATE_HIR_ID { + // We walk up the node tree until we hit the root or the parent + // of the opaque type. + while hir_id != mod_id && node_id != ast::CRATE_HIR_ID { hir_id = tcx.hir().get_parent_item(hir_id); } - // syntactically we are allowed to define the concrete type + // Syntactically we are allowed to define the concrete type. hir_id == mod_id } diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 7c57c50595bc8..2e56ca6f56352 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -1,6 +1,6 @@ //! Name resolution for lifetimes. //! -//! Name resolution for lifetimes follows MUCH simpler rules than the +//! Name resolution for lifetimes follows *much* simpler rules than the //! full resolve. For example, lifetime names are never exported or //! used between functions, and they operate in a purely top-down //! way. Therefore, we break lifetime name resolution into a separate pass. @@ -1009,7 +1009,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { trait_ref: &'tcx hir::PolyTraitRef, _modifier: hir::TraitBoundModifier, ) { - debug!("visit_poly_trait_ref trait_ref={:?}", trait_ref); + debug!("visit_poly_trait_ref(trait_ref={:?})", trait_ref); if !self.trait_ref_hack || trait_ref.bound_generic_params.iter().any(|param| { match param.kind { diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index b81a4538d971d..815c68b6b1cb6 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -124,12 +124,12 @@ impl<'a, 'tcx: 'a> Annotator<'a, 'tcx> { // This crate explicitly wants staged API. debug!("annotate(id = {:?}, attrs = {:?})", hir_id, attrs); if let Some(..) = attr::find_deprecation(&self.tcx.sess.parse_sess, attrs, item_sp) { - self.tcx.sess.span_err(item_sp, "`#[deprecated]` cannot be used in staged api, \ + self.tcx.sess.span_err(item_sp, "`#[deprecated]` cannot be used in staged API; \ use `#[rustc_deprecated]` instead"); } if let Some(mut stab) = attr::find_stability(&self.tcx.sess.parse_sess, attrs, item_sp) { - // Error if prohibited, or can't inherit anything from a container + // Error if prohibited, or can't inherit anything from a container. if kind == AnnotationKind::Prohibited || (kind == AnnotationKind::Container && stab.level.is_stable() && diff --git a/src/librustc/mir/interpret/error.rs b/src/librustc/mir/interpret/error.rs index ac7c07c366d51..b4615aeb0db15 100644 --- a/src/librustc/mir/interpret/error.rs +++ b/src/librustc/mir/interpret/error.rs @@ -49,7 +49,8 @@ pub struct ConstEvalErr<'tcx> { #[derive(Clone, Debug, RustcEncodable, RustcDecodable, HashStable)] pub struct FrameInfo<'tcx> { - pub call_site: Span, // this span is in the caller! + /// This span is in the caller. + pub call_site: Span, pub instance: ty::Instance<'tcx>, pub lint_root: Option, } @@ -200,12 +201,12 @@ fn print_backtrace(backtrace: &mut Backtrace) { impl<'tcx> From> for EvalError<'tcx> { fn from(kind: InterpError<'tcx, u64>) -> Self { let backtrace = match env::var("RUST_CTFE_BACKTRACE") { - // matching RUST_BACKTRACE, we treat "0" the same as "not present". + // Matching `RUST_BACKTRACE` -- we treat "0" the same as "not present". Ok(ref val) if val != "0" => { let mut backtrace = Backtrace::new_unresolved(); if val == "immediate" { - // Print it now + // Print it now. print_backtrace(&mut backtrace); None } else { diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 95312d55b3be1..9f22e6a108891 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -662,7 +662,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { "{}", message.unwrap_or_else(|| format!("the trait bound `{}` is not satisfied{}", - trait_ref.to_predicate(), post_message) + trait_ref.to_predicate(), post_message) )); let explanation = @@ -676,7 +676,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { }; if let Some(ref s) = label { - // If it has a custom "#[rustc_on_unimplemented]" + // If it has a custom `#[rustc_on_unimplemented]` // error message, let's display it as the label! err.span_label(span, s.as_str()); err.help(&explanation); @@ -684,7 +684,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { err.span_label(span, explanation); } if let Some(ref s) = note { - // If it has a custom "#[rustc_on_unimplemented]" note, let's display it + // If it has a custom `#[rustc_on_unimplemented]` note, let's display it err.note(s.as_str()); } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index ba96233b85328..fc9756d52f55d 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1465,9 +1465,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let predicate = self.infcx() .resolve_vars_if_possible(&obligation.predicate); - // OK to skip binder because of the nature of the + // Okay to skip binder because of the nature of the // trait-ref-is-knowable check, which does not care about - // bound regions + // bound regions. let trait_ref = predicate.skip_binder().trait_ref; let result = coherence::trait_ref_is_knowable(self.tcx(), trait_ref); @@ -1853,7 +1853,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { let matching_bounds = all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id()); - // keep only those bounds which may apply, and propagate overflow if it occurs + // Keep only those bounds which may apply, and propagate overflow if it occurs. let mut param_candidates = vec![]; for bound in matching_bounds { let wc = self.evaluate_where_clause(stack, bound.clone())?; @@ -1891,9 +1891,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Ok(()); } - // OK to skip binder because the substs on generator types never + // Okay to skip binder because the substs on generator types never // touch bound regions, they just capture the in-scope - // type/region parameters + // type/region parameters. let self_ty = *obligation.self_ty().skip_binder(); match self_ty.sty { ty::Generator(..) => { @@ -1935,7 +1935,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { } }; - // OK to skip binder because the substs on closure types never + // Okay to skip binder because the substs on closure types never // touch bound regions, they just capture the in-scope // type/region parameters match obligation.self_ty().skip_binder().sty { @@ -1985,7 +1985,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { return Ok(()); } - // OK to skip binder because what we are inspecting doesn't involve bound regions + // Okay to skip binder because what we are inspecting doesn't involve bound regions let self_ty = *obligation.self_ty().skip_binder(); match self_ty.sty { ty::Infer(ty::TyVar(_)) => { @@ -2042,7 +2042,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) -> Result<(), SelectionError<'tcx>> { - // OK to skip binder here because the tests we do below do not involve bound regions + // Okay to skip binder here because the tests we do below do not involve bound regions. let self_ty = *obligation.self_ty().skip_binder(); debug!("assemble_candidates_from_auto_impls(self_ty={:?})", self_ty); @@ -2274,7 +2274,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { obligation: &TraitObligation<'tcx>, candidates: &mut SelectionCandidateSet<'tcx>, ) -> Result<(), SelectionError<'tcx>> { - // OK to skip binder here because the tests we do below do not involve bound regions + // Okay to skip binder here because the tests we do below do not involve bound regions. let self_ty = *obligation.self_ty().skip_binder(); debug!("assemble_candidates_for_trait_alias(self_ty={:?})", self_ty); @@ -3094,7 +3094,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { ) -> Result>, SelectionError<'tcx>> { debug!("confirm_fn_pointer_candidate({:?})", obligation); - // OK to skip binder; it is reintroduced below + // Okay to skip binder; it is reintroduced below. let self_ty = self.infcx .shallow_resolve(*obligation.self_ty().skip_binder()); let sig = self_ty.fn_sig(self.tcx()); @@ -3172,9 +3172,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { &mut self, obligation: &TraitObligation<'tcx>, ) -> Result>, SelectionError<'tcx>> { - // OK to skip binder because the substs on generator types never + // Okay to skip binder because the substs on generator types never // touch bound regions, they just capture the in-scope - // type/region parameters + // type/region parameters. let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder()); let (generator_def_id, substs) = match self_ty.sty { ty::Generator(id, substs, _) => (id, substs), @@ -3229,9 +3229,9 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .fn_trait_kind(obligation.predicate.def_id()) .unwrap_or_else(|| bug!("closure candidate for non-fn trait {:?}", obligation)); - // OK to skip binder because the substs on closure types never + // Okay to skip binder because the substs on closure types never // touch bound regions, they just capture the in-scope - // type/region parameters + // type/region parameters. let self_ty = self.infcx.shallow_resolve(*obligation.self_ty().skip_binder()); let (closure_def_id, substs) = match self_ty.sty { ty::Closure(id, substs) => (id, substs), diff --git a/src/librustc/traits/structural_impls.rs b/src/librustc/traits/structural_impls.rs index 404fadbc78afc..4d382d6c45a76 100644 --- a/src/librustc/traits/structural_impls.rs +++ b/src/librustc/traits/structural_impls.rs @@ -10,11 +10,11 @@ use std::fmt; use std::rc::Rc; use std::collections::{BTreeSet, BTreeMap}; -// structural impls for the structs in traits +// Structural impls for the structs in `traits`. impl<'tcx, T: fmt::Debug> fmt::Debug for Normalized<'tcx, T> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - write!(f, "Normalized({:?},{:?})", self.value, self.obligations) + write!(f, "Normalized({:?}, {:?})", self.value, self.obligations) } } @@ -23,13 +23,13 @@ impl<'tcx, O: fmt::Debug> fmt::Debug for traits::Obligation<'tcx, O> { if ty::tls::with(|tcx| tcx.sess.verbose()) { write!( f, - "Obligation(predicate={:?},cause={:?},param_env={:?},depth={})", + "Obligation(predicate={:?}, cause={:?}, param_env={:?}, depth={})", self.predicate, self.cause, self.param_env, self.recursion_depth ) } else { write!( f, - "Obligation(predicate={:?},depth={})", + "Obligation(predicate={:?}, depth={})", self.predicate, self.recursion_depth ) } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 2599b8fbf6ff1..e60022033cc54 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1706,21 +1706,21 @@ impl<'gcx> GlobalCtxt<'gcx> { } } -/// A trait implemented for all X<'a> types which can be safely and -/// efficiently converted to X<'tcx> as long as they are part of the -/// provided TyCtxt<'tcx>. -/// This can be done, for example, for Ty<'tcx> or SubstsRef<'tcx> +/// A trait implemented for all `X<'a>` types that can be safely and +/// efficiently converted to `X<'tcx>` as long as they are part of the +/// provided `TyCtxt<'tcx>`. +/// This can be done, for example, for `Ty<'tcx>` or `SubstsRef<'tcx>` /// by looking them up in their respective interners. /// /// However, this is still not the best implementation as it does /// need to compare the components, even for interned values. -/// It would be more efficient if TypedArena provided a way to +/// It would be more efficient if `TypedArena` provided a way to /// determine whether the address is in the allocated range. /// /// None is returned if the value or one of the components is not part /// of the provided context. -/// For Ty, None can be returned if either the type interner doesn't -/// contain the TyKind key or if the address of the interned +/// For `Ty`, `None` can be returned if either the type interner doesn't +/// contain the `TyKind` key or if the address of the interned /// pointer differs. The latter case is possible if a primitive type, /// e.g., `()` or `u8`, was interned in a different context. pub trait Lift<'tcx>: fmt::Debug { diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index e585f9939a014..69bf05c66f394 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1090,7 +1090,7 @@ pub enum Predicate<'tcx> { /// See the `ProjectionPredicate` struct for details. Projection(PolyProjectionPredicate<'tcx>), - /// no syntax: `T` well-formed + /// No syntax: `T` well-formed. WellFormed(Ty<'tcx>), /// Trait must be object-safe. @@ -1245,19 +1245,17 @@ impl<'tcx> TraitPredicate<'tcx> { impl<'tcx> PolyTraitPredicate<'tcx> { pub fn def_id(&self) -> DefId { - // ok to skip binder since trait def-id does not care about regions + // Ok to skip binder since trait def-ID does not care about regions. self.skip_binder().def_id() } } #[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Debug, RustcEncodable, RustcDecodable, HashStable)] -pub struct OutlivesPredicate(pub A, pub B); // `A: B` -pub type PolyOutlivesPredicate = ty::Binder>; -pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate, - ty::Region<'tcx>>; -pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, - ty::Region<'tcx>>; +pub struct OutlivesPredicate(pub A, pub B); // `A: B` +pub type PolyOutlivesPredicate = ty::Binder>; +pub type RegionOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'tcx>>; +pub type TypeOutlivesPredicate<'tcx> = OutlivesPredicate, ty::Region<'tcx>>; pub type PolyRegionOutlivesPredicate<'tcx> = ty::Binder>; pub type PolyTypeOutlivesPredicate<'tcx> = ty::Binder>; @@ -1314,7 +1312,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> { /// Note that this is not the `DefId` of the `TraitRef` containing this /// associated type, which is in `tcx.associated_item(projection_def_id()).container`. pub fn projection_def_id(&self) -> DefId { - // okay to skip binder since trait def-id does not care about regions + // Ok to skip binder since trait def-ID does not care about regions. self.skip_binder().projection_ty.item_def_id } } @@ -1371,7 +1369,7 @@ impl<'tcx> ToPredicate<'tcx> for PolyProjectionPredicate<'tcx> { } } -// A custom iterator used by Predicate::walk_tys. +// A custom iterator used by `Predicate::walk_tys`. enum WalkTysIter<'tcx, I, J, K> where I: Iterator>, J: Iterator>, @@ -1505,7 +1503,7 @@ impl<'tcx> Predicate<'tcx> { /// /// Example: /// -/// struct Foo> { ... } +/// struct Foo> { ... } /// /// Here, the `GenericPredicates` for `Foo` would contain a list of bounds like /// `[[], [U:Bar]]`. Now if there were some particular reference @@ -2785,10 +2783,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { e.span } Some(f) => { - bug!("Node id {} is not an expr: {:?}", id, f); + bug!("node-ID {} is not an expr: {:?}", id, f); } None => { - bug!("Node id {} is not present in the node map", id); + bug!("node-ID {} is not present in the node map", id); } } } diff --git a/src/librustc/ty/query/plumbing.rs b/src/librustc/ty/query/plumbing.rs index d671b58470c6a..c2760ccb0c0a2 100644 --- a/src/librustc/ty/query/plumbing.rs +++ b/src/librustc/ty/query/plumbing.rs @@ -96,12 +96,12 @@ pub(super) struct JobOwner<'a, 'tcx: 'a, Q: QueryDescription<'tcx> + 'a> { } impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { - /// Either gets a JobOwner corresponding the query, allowing us to + /// Either gets a `JobOwner` corresponding the query, allowing us to /// start executing the query, or it returns with the result of the query. /// If the query is executing elsewhere, this will wait for it. /// If the query panicked, this will silently panic. /// - /// This function is inlined because that results in a noticeable speedup + /// This function is inlined because that results in a noticeable speed-up /// for some compile-time benchmarks. #[inline(always)] pub(super) fn try_get( @@ -126,9 +126,9 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { Entry::Occupied(entry) => { match *entry.get() { QueryResult::Started(ref job) => { - //For parallel queries, we'll block and wait until the query running - //in another thread has completed. Record how long we wait in the - //self-profiler + // For parallel queries, we'll block and wait until the query running + // in another thread has completed. Record how long we wait in the + // self-profiler. #[cfg(parallel_compiler)] tcx.sess.profiler(|p| p.query_blocked_start(Q::NAME)); @@ -138,7 +138,7 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { } } Entry::Vacant(entry) => { - // No job entry for this query. Return a new one to be started later + // No job entry for this query. Return a new one to be started later. return tls::with_related_context(tcx, |icx| { // Create the `parent` variable before `info`. This allows LLVM // to elide the move of `info` @@ -161,14 +161,14 @@ impl<'a, 'tcx, Q: QueryDescription<'tcx>> JobOwner<'a, 'tcx, Q> { mem::drop(lock); // If we are single-threaded we know that we have cycle error, - // so we just return the error + // so we just return the error. #[cfg(not(parallel_compiler))] return TryGetJob::Cycle(cold_path(|| { Q::handle_cycle_error(tcx, job.find_cycle_in_stack(tcx, span)) })); // With parallel queries we might just have to wait on some other - // thread + // thread. #[cfg(parallel_compiler)] { let result = job.r#await(tcx, span); @@ -636,8 +636,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { profq_query_msg!(Q::NAME.as_str(), self, key)) ); - // We may be concurrently trying both execute and force a query - // Ensure that only one of them runs the query + // We may be concurrently trying both execute and force a query. + // Ensure that only one of them runs the query. let job = match JobOwner::try_get(self, span, &key) { TryGetJob::NotYetStarted(job) => job, TryGetJob::Cycle(_) | @@ -731,7 +731,7 @@ macro_rules! define_queries_inner { let mut jobs = Vec::new(); // We use try_lock here since we are only called from the - // deadlock handler, and this shouldn't be locked + // deadlock handler, and this shouldn't be locked. $( jobs.extend( self.$name.try_lock().unwrap().active.values().filter_map(|v| diff --git a/src/librustc/ty/util.rs b/src/librustc/ty/util.rs index 926c0f8b94919..9b4029f409ba4 100644 --- a/src/librustc/ty/util.rs +++ b/src/librustc/ty/util.rs @@ -546,7 +546,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.def_key(def_id).disambiguated_data.data == DefPathData::Ctor } - /// Given the `DefId` of a fn or closure, returns the `DefId` of + /// Given the def-ID of a fn or closure, returns the def-ID of /// the innermost fn item that the closure is contained within. /// This is a significant `DefId` because, when we do /// type-checking, we type-check this fn item and all of its diff --git a/src/librustc/util/common.rs b/src/librustc/util/common.rs index 67eaa19c080b5..2140018223c34 100644 --- a/src/librustc/util/common.rs +++ b/src/librustc/util/common.rs @@ -18,7 +18,7 @@ use crate::dep_graph::{DepNode}; use lazy_static; use crate::session::Session; -// The name of the associated type for `Fn` return types +// The name of the associated type for `Fn` return types. pub const FN_OUTPUT_NAME: Symbol = sym::Output; // Useful type to use with `Result<>` indicate that an error has already @@ -45,16 +45,16 @@ fn panic_hook(info: &panic::PanicInfo<'_>) { TyCtxt::try_print_query_stack(); } - #[cfg(windows)] - unsafe { - if env::var("RUSTC_BREAK_ON_ICE").is_ok() { - extern "system" { - fn DebugBreak(); - } - // Trigger a debugger if we crashed during bootstrap - DebugBreak(); + #[cfg(windows)] + unsafe { + if env::var("RUSTC_BREAK_ON_ICE").is_ok() { + extern "system" { + fn DebugBreak(); } + // Trigger a debugger if we crashed during bootstrap. + DebugBreak(); } + } } pub fn install_panic_hook() { @@ -80,42 +80,42 @@ pub struct QueryMsg { } /// A sequence of these messages induce a trace of query-based incremental compilation. -/// FIXME(matthewhammer): Determine whether we should include cycle detection here or not. +// FIXME(matthewhammer): Determine whether we should include cycle detection here or not. #[derive(Clone,Debug)] pub enum ProfileQueriesMsg { - /// begin a timed pass + /// Begin a timed pass. TimeBegin(String), - /// end a timed pass + /// End a timed pass. TimeEnd, - /// begin a task (see dep_graph::graph::with_task) + /// Begin a task (see `dep_graph::graph::with_task`). TaskBegin(DepNode), - /// end a task + /// End a task. TaskEnd, - /// begin a new query - /// can't use `Span` because queries are sent to other thread + /// Begin a new query. + /// Cannot use `Span` because queries are sent to other thread. QueryBegin(SpanData, QueryMsg), - /// query is satisfied by using an already-known value for the given key + /// Query is satisfied by using an already-known value for the given key. CacheHit, - /// query requires running a provider; providers may nest, permitting queries to nest. + /// Query requires running a provider; providers may nest, permitting queries to nest. ProviderBegin, - /// query is satisfied by a provider terminating with a value + /// Query is satisfied by a provider terminating with a value. ProviderEnd, - /// dump a record of the queries to the given path + /// Dump a record of the queries to the given path. Dump(ProfQDumpParams), - /// halt the profiling/monitoring background thread + /// Halt the profiling/monitoring background thread. Halt } -/// If enabled, send a message to the profile-queries thread +/// If enabled, send a message to the profile-queries thread. pub fn profq_msg(sess: &Session, msg: ProfileQueriesMsg) { if let Some(s) = sess.profile_channel.borrow().as_ref() { s.send(msg).unwrap() } else { - // Do nothing + // Do nothing. } } -/// Set channel for profile queries channel +/// Set channel for profile queries channel. pub fn profq_set_chan(sess: &Session, s: Sender) -> bool { let mut channel = sess.profile_channel.borrow_mut(); if channel.is_none() { diff --git a/src/librustc_borrowck/dataflow.rs b/src/librustc_borrowck/dataflow.rs index de2a3c4cb22a8..af10404cba395 100644 --- a/src/librustc_borrowck/dataflow.rs +++ b/src/librustc_borrowck/dataflow.rs @@ -19,7 +19,6 @@ use rustc::hir; use rustc::hir::intravisit; use rustc::hir::print as pprust; - #[derive(Copy, Clone, Debug)] pub enum EntryOrExit { Entry, @@ -92,7 +91,7 @@ fn get_cfg_indices<'a>(id: hir::ItemLocalId, index.get(&id).map_or(&[], |v| &v[..]) } -impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { +impl<'a, 'tcx, O: DataFlowOperator> DataFlowContext<'a, 'tcx, O> { fn has_bitset_for_local_id(&self, n: hir::ItemLocalId) -> bool { assert!(n != hir::DUMMY_ITEM_LOCAL_ID); self.local_id_to_index.contains_key(&n) @@ -225,7 +224,7 @@ pub enum KillFrom { Execution, } -impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { +impl<'a, 'tcx, O: DataFlowOperator> DataFlowContext<'a, 'tcx, O> { pub fn new(tcx: TyCtxt<'a, 'tcx, 'tcx>, analysis_name: &'static str, body: Option<&hir::Body>, @@ -500,8 +499,8 @@ impl<'a, 'tcx, O:DataFlowOperator> DataFlowContext<'a, 'tcx, O> { } } -impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> { -// ^^^^^^^^^^^^^ only needed for pretty printing +// N.B. `Clone + 'static` only needed for pretty printing. +impl<'a, 'tcx, O: DataFlowOperator + Clone + 'static> DataFlowContext<'a, 'tcx, O> { pub fn propagate(&mut self, cfg: &cfg::CFG, body: &hir::Body) { //! Performs the data flow analysis. @@ -538,7 +537,7 @@ impl<'a, 'tcx, O:DataFlowOperator+Clone+'static> DataFlowContext<'a, 'tcx, O> { } } -impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> { +impl<'a, 'b, 'tcx, O: DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> { fn walk_cfg(&mut self, cfg: &cfg::CFG, nodes_po: &[CFGIndex], @@ -547,7 +546,7 @@ impl<'a, 'b, 'tcx, O:DataFlowOperator> PropagationContext<'a, 'b, 'tcx, O> { bits_to_string(in_out), self.dfcx.analysis_name); assert!(self.dfcx.bits_per_id > 0); - // Iterate over nodes in reverse postorder + // Iterate over nodes in reverse post-order. for &node_index in nodes_po.iter().rev() { let node = cfg.graph.node(node_index); debug!("DataFlowContext::walk_cfg idx={:?} id={:?} begin in_out={}", @@ -631,9 +630,9 @@ fn bits_to_string(words: &[usize]) -> String { } #[inline] -fn bitwise(out_vec: &mut [usize], - in_vec: &[usize], - op: &Op) -> bool { +fn bitwise(out_vec: &mut [usize], + in_vec: &[usize], + op: &Op) -> bool { assert_eq!(out_vec.len(), in_vec.len()); let mut changed = false; for (out_elt, in_elt) in out_vec.iter_mut().zip(in_vec) { diff --git a/src/librustc_codegen_llvm/intrinsic.rs b/src/librustc_codegen_llvm/intrinsic.rs index 42aa9989346fc..f32dc43126540 100644 --- a/src/librustc_codegen_llvm/intrinsic.rs +++ b/src/librustc_codegen_llvm/intrinsic.rs @@ -937,8 +937,8 @@ fn codegen_msvc_try( bx.store(ret, dest, i32_align); } -// Definition of the standard "try" function for Rust using the GNU-like model -// of exceptions (e.g., the normal semantics of LLVM's landingpad and invoke +// Definition of the standard `try` function for Rust using the GNU-like model +// of exceptions (e.g., the normal semantics of LLVM's `landingpad` and `invoke` // instructions). // // This codegen is a little surprising because we always call a shim diff --git a/src/librustc_codegen_ssa/back/link.rs b/src/librustc_codegen_ssa/back/link.rs index c1ec2071789eb..0ba5451bd72f5 100644 --- a/src/librustc_codegen_ssa/back/link.rs +++ b/src/librustc_codegen_ssa/back/link.rs @@ -1127,10 +1127,10 @@ fn link_args<'a, B: ArchiveBuilder<'a>>(cmd: &mut dyn Linker, // For this reason, we have organized the arguments we pass to the linker as // such: // - // 1. The local object that LLVM just generated - // 2. Local native libraries - // 3. Upstream rust libraries - // 4. Upstream native libraries + // 1. The local object that LLVM just generated + // 2. Local native libraries + // 3. Upstream rust libraries + // 4. Upstream native libraries // // The rationale behind this ordering is that those items lower down in the // list can't depend on items higher up in the list. For example nothing can diff --git a/src/librustc_codegen_ssa/mir/block.rs b/src/librustc_codegen_ssa/mir/block.rs index 4c9313a330921..7e5ee25d8ef78 100644 --- a/src/librustc_codegen_ssa/mir/block.rs +++ b/src/librustc_codegen_ssa/mir/block.rs @@ -967,7 +967,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { bx.range_metadata(llval, 0..2); } } - // We store bools as i8 so we need to truncate to i1. + // We store bools as `i8` so we need to truncate to `i1`. llval = base::to_immediate(bx, llval, arg.layout); } } @@ -1097,7 +1097,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { fn_ret: &ArgType<'tcx, Ty<'tcx>>, llargs: &mut Vec, is_intrinsic: bool ) -> ReturnDest<'tcx, Bx::Value> { - // If the return is ignored, we can just return a do-nothing ReturnDest + // If the return is ignored, we can just return a do-nothing `ReturnDest`. if fn_ret.is_ignore() { return ReturnDest::Nothing; } @@ -1106,8 +1106,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { LocalRef::Place(dest) => dest, LocalRef::UnsizedPlace(_) => bug!("return type must be sized"), LocalRef::Operand(None) => { - // Handle temporary places, specifically Operand ones, as - // they don't have allocas + // Handle temporary places, specifically `Operand` ones, as + // they don't have `alloca`s. return if fn_ret.is_indirect() { // Odd, but possible, case, we have an operand temporary, // but the calling convention has an indirect return. @@ -1117,8 +1117,8 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { ReturnDest::IndirectOperand(tmp, index) } else if is_intrinsic { // Currently, intrinsics always need a location to store - // the result. so we create a temporary alloca for the - // result + // the result, so we create a temporary `alloca` for the + // result. let tmp = PlaceRef::alloca(bx, fn_ret.layout, "tmp_ret"); tmp.storage_live(bx); ReturnDest::IndirectOperand(tmp, index) @@ -1137,7 +1137,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { if dest.align < dest.layout.align.abi { // Currently, MIR code generation does not create calls // that store directly to fields of packed structs (in - // fact, the calls it creates write only to temps), + // fact, the calls it creates write only to temps). // // If someone changes that, please update this code path // to create a temporary. @@ -1232,12 +1232,12 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } enum ReturnDest<'tcx, V> { - // Do nothing, the return value is indirect or ignored + // Do nothing; the return value is indirect or ignored. Nothing, - // Store the return value to the pointer + // Store the return value to the pointer. Store(PlaceRef<'tcx, V>), - // Stores an indirect return value to an operand local place + // Store an indirect return value to an operand local place. IndirectOperand(PlaceRef<'tcx, V>, mir::Local), - // Stores a direct return value to an operand local place + // Store a direct return value to an operand local place. DirectOperand(mir::Local) } diff --git a/src/librustc_codegen_ssa/mir/place.rs b/src/librustc_codegen_ssa/mir/place.rs index cd32d6f484d73..27311d0a8fbf1 100644 --- a/src/librustc_codegen_ssa/mir/place.rs +++ b/src/librustc_codegen_ssa/mir/place.rs @@ -120,7 +120,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { bx.struct_gep(self.llval, bx.cx().backend_field_index(self.layout, ix)) }; PlaceRef { - // HACK(eddyb) have to bitcast pointers until LLVM removes pointee types. + // HACK(eddyb): have to bitcast pointers until LLVM removes pointee types. llval: bx.pointercast(llval, bx.cx().type_ptr_to(bx.cx().backend_type(field))), llextra: if bx.cx().type_has_metadata(field.ty) { self.llextra @@ -134,7 +134,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { // Simple cases, which don't need DST adjustment: // * no metadata available - just log the case - // * known alignment - sized types, [T], str or a foreign type + // * known alignment - sized types, `[T]`, `str` or a foreign type // * packed struct - there is no alignment padding match field.ty.sty { _ if self.llextra.is_none() => { @@ -156,18 +156,19 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { } // We need to get the pointer manually now. - // We do this by casting to a *i8, then offsetting it by the appropriate amount. + // We do this by casting to a `*i8`, then offsetting it by the appropriate amount. // We do this instead of, say, simply adjusting the pointer from the result of a GEP // because the field may have an arbitrary alignment in the LLVM representation // anyway. // // To demonstrate: - // struct Foo { - // x: u16, - // y: T - // } // - // The type Foo> is represented in LLVM as { u16, { u16, u8 }}, meaning that + // struct Foo { + // x: u16, + // y: T + // } + // + // The type `Foo>` is represented in LLVM as `{ u16, { u16, u8 }}`, meaning that // the `y` field has 16-bit alignment. let meta = self.llextra; @@ -180,9 +181,9 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { // Bump the unaligned offset up to the appropriate alignment using the // following expression: // - // (unaligned offset + (align - 1)) & -align + // (unaligned offset + (align - 1)) & -align - // Calculate offset + // Calculate offset. let align_sub_1 = bx.sub(unsized_align, bx.cx().const_usize(1u64)); let and_lhs = bx.add(unaligned_offset, align_sub_1); let and_rhs = bx.neg(unsized_align); @@ -190,11 +191,11 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { debug!("struct_field_ptr: DST field offset: {:?}", offset); - // Cast and adjust pointer + // Cast and adjust pointer. let byte_ptr = bx.pointercast(self.llval, bx.cx().type_i8p()); let byte_ptr = bx.gep(byte_ptr, &[offset]); - // Finally, cast back to the type expected + // Finally, cast back to the type expected. let ll_fty = bx.cx().backend_type(field); debug!("struct_field_ptr: Field type is {:?}", ll_fty); @@ -235,7 +236,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { // We use `i1` for bytes that are always `0` or `1`, // e.g., `#[repr(i8)] enum E { A, B }`, but we can't // let LLVM interpret the `i1` as signed, because - // then `i1 1` (i.e., E::B) is effectively `i8 -1`. + // then `i1 1` (i.e., `E::B`) is effectively `i8 -1`. layout::Int(_, signed) => !discr_scalar.is_bool() && signed, _ => false }; @@ -248,9 +249,9 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { } => { let niche_llty = bx.cx().immediate_backend_type(discr.layout); if niche_variants.start() == niche_variants.end() { - // FIXME(eddyb) Check the actual primitive type here. + // FIXME(eddyb): check the actual primitive type here. let niche_llval = if niche_start == 0 { - // HACK(eddyb) Using `c_null` as it works on all types. + // HACK(eddyb): using `c_null` as it works on all types. bx.cx().const_null(niche_llty) } else { bx.cx().const_uint_big(niche_llty, niche_start) @@ -314,7 +315,7 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { if variant_index != dataful_variant { if bx.cx().sess().target.target.arch == "arm" || bx.cx().sess().target.target.arch == "aarch64" { - // Issue #34427: As workaround for LLVM bug on ARM, + // FIXME(#34427): as workaround for LLVM bug on ARM, // use memset of 0 before assigning niche value. let fill_byte = bx.cx().const_u8(0); let size = bx.cx().const_usize(self.layout.size.bytes()); @@ -326,9 +327,9 @@ impl<'a, 'tcx: 'a, V: CodegenObject> PlaceRef<'tcx, V> { let niche_value = variant_index.as_u32() - niche_variants.start().as_u32(); let niche_value = (niche_value as u128) .wrapping_add(niche_start); - // FIXME(eddyb) Check the actual primitive type here. + // FIXME(eddyb): check the actual primitive type here. let niche_llval = if niche_value == 0 { - // HACK(eddyb) Using `c_null` as it works on all types. + // HACK(eddyb): using `c_null` as it works on all types. bx.cx().const_null(niche_llty) } else { bx.cx().const_uint_big(niche_llty, niche_value) @@ -429,10 +430,10 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { _ => bug!("promoteds should have an allocation: {:?}", val), }, Err(_) => { - // this is unreachable as long as runtime + // This is unreachable as long as runtime // and compile-time agree on values - // With floats that won't always be true - // so we generate an abort + // With floats that won't always be true, + // so we generate an abort. bx.abort(); let llval = bx.cx().const_undef( bx.cx().type_ptr_to(bx.cx().backend_type(layout)) @@ -502,7 +503,7 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> { } // Cast the place pointer type to the new - // array or slice type (*[%_; new_len]). + // array or slice type (`*[%_; new_len]`). subslice.llval = bx.pointercast(subslice.llval, bx.cx().type_ptr_to(bx.cx().backend_type(subslice.layout))); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index f9a12c19e4276..937085c8ad8e8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -196,7 +196,7 @@ declare_lint_pass!(UnsafeCode => [UNSAFE_CODE]); impl UnsafeCode { fn report_unsafe(&self, cx: &EarlyContext<'_>, span: Span, desc: &'static str) { - // This comes from a macro that has #[allow_internal_unsafe]. + // This comes from a macro that has `#[allow_internal_unsafe]`. if span.allows_unsafe() { return; } @@ -216,7 +216,7 @@ impl EarlyLintPass for UnsafeCode { fn check_expr(&mut self, cx: &EarlyContext<'_>, e: &ast::Expr) { if let ast::ExprKind::Block(ref blk, _) = e.node { - // Don't warn about generated blocks, that'll just pollute the output. + // Don't warn about generated blocks; that'll just pollute the output. if blk.rules == ast::BlockCheckMode::Unsafe(ast::UserProvided) { self.report_unsafe(cx, blk.span, "usage of an `unsafe` block"); } @@ -335,7 +335,7 @@ impl MissingDoc { // Only check publicly-visible items, using the result from the privacy pass. // It's an option so the crate root can also use this function (it doesn't - // have a NodeId). + // have a `NodeId`). if let Some(id) = id { if !cx.access_levels.is_exported(id) { return; @@ -389,7 +389,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { hir::ItemKind::Struct(..) => "a struct", hir::ItemKind::Union(..) => "a union", hir::ItemKind::Trait(.., ref trait_item_refs) => { - // Issue #11592, traits are always considered exported, even when private. + // Issue #11592: traits are always considered exported, even when private. if let hir::VisibilityKind::Inherited = it.vis.node { self.private_traits.insert(it.hir_id); for trait_item_ref in trait_item_refs { @@ -401,7 +401,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { } hir::ItemKind::Ty(..) => "a type alias", hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) => { - // If the trait is private, add the impl items to private_traits so they don't get + // If the trait is private, add the impl items to `private_traits` so they don't get // reported for missing docs. let real_trait = trait_ref.path.res.def_id(); if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(real_trait) { @@ -1215,7 +1215,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TrivialConstraints { use rustc::ty::fold::TypeFoldable; use rustc::ty::Predicate::*; - if cx.tcx.features().trivial_bounds { let def_id = cx.tcx.hir().local_def_id_from_hir_id(item.hir_id); let predicates = cx.tcx.predicates_of(def_id); @@ -1464,7 +1463,7 @@ impl KeywordIdents { _ => return, }; - // don't lint `r#foo` + // Don't lint `r#foo`. if cx.sess.parse_sess.raw_identifier_spans.borrow().contains(&ident.span) { return; } @@ -1717,8 +1716,6 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for ExplicitOutlivesRequirements { ); err.emit(); } - } } - } diff --git a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs index db43ea0558cc7..3bf0f7e04d295 100644 --- a/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs +++ b/src/librustc_mir/borrow_check/nll/region_infer/error_reporting/mod.rs @@ -576,7 +576,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { /// Adds a suggestion to errors where a `impl Trait` is returned. /// /// ```text - /// help: to allow this impl Trait to capture borrowed data with lifetime `'1`, add `'_` as + /// help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as /// a constraint /// | /// LL | fn iter_values_anon(&self) -> impl Iterator + 'a { @@ -652,7 +652,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { diag.span_suggestion( span, &format!( - "to allow this impl Trait to capture borrowed data with lifetime \ + "to allow this `impl Trait` to capture borrowed data with lifetime \ `{}`, add `{}` as a constraint", fr_name, suggestable_fr_name, ), diff --git a/src/librustc_mir/build/mod.rs b/src/librustc_mir/build/mod.rs index 91106ebd77e07..7ca54a430a505 100644 --- a/src/librustc_mir/build/mod.rs +++ b/src/librustc_mir/build/mod.rs @@ -289,9 +289,9 @@ pub enum BlockFrame { /// Evaluation is currently within a statement. /// /// Examples include: - /// 1. `EXPR;` - /// 2. `let _ = EXPR;` - /// 3. `let x = EXPR;` + /// 1. `EXPR;` + /// 2. `let _ = EXPR;` + /// 3. `let x = EXPR;` Statement { /// If true, then statement discards result from evaluating /// the expression (such as examples 1 and 2 above). diff --git a/src/librustc_mir/monomorphize/partitioning.rs b/src/librustc_mir/monomorphize/partitioning.rs index 1895d4871552e..2c84364216633 100644 --- a/src/librustc_mir/monomorphize/partitioning.rs +++ b/src/librustc_mir/monomorphize/partitioning.rs @@ -90,7 +90,7 @@ //! //! Note though that as a side-effect of creating a codegen units per //! source-level module, functions from the same module will be available for -//! inlining, even when they are not marked #[inline]. +//! inlining, even when they are not marked `#[inline]`. use std::collections::hash_map::Entry; use std::cmp; @@ -152,7 +152,7 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // In the next step, we use the inlining map to determine which additional // monomorphizations have to go into each codegen unit. These additional // monomorphizations can be drop-glue, functions from external crates, and - // local functions the definition of which is marked with #[inline]. + // local functions the definition of which is marked with `#[inline]`. let mut post_inlining = place_inlined_mono_items(initial_partitioning, inlining_map); @@ -166,7 +166,7 @@ pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, internalize_symbols(tcx, &mut post_inlining, inlining_map); } - // Finally, sort by codegen unit name, so that we get deterministic results + // Finally, sort by codegen unit name, so that we get deterministic results. let PostInliningPartitioning { codegen_units: mut result, mono_item_placements: _, @@ -258,8 +258,8 @@ fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>, roots.insert(mono_item); } - // always ensure we have at least one CGU; otherwise, if we have a - // crate with just types (for example), we could wind up with no CGU + // Always ensure we have at least one CGU; otherwise, if we have a + // crate with just types (for example), we could wind up with no CGU. if codegen_units.is_empty() { let codegen_unit_name = fallback_cgu_name(cgu_name_builder); codegen_units.insert(codegen_unit_name.clone(), @@ -300,10 +300,10 @@ fn mono_item_visibility( export_generics: bool, ) -> Visibility { let instance = match mono_item { - // This is pretty complicated, go below + // This is pretty complicated; see below. MonoItem::Fn(instance) => instance, - // Misc handling for generics and such, but otherwise + // Misc handling for generics and such, but otherwise: MonoItem::Static(def_id) => { return if tcx.is_reachable_non_generic(*def_id) { *can_be_internalized = false; @@ -358,11 +358,10 @@ fn mono_item_visibility( let is_generic = instance.substs.non_erasable_generics().next().is_some(); - // Upstream `DefId` instances get different handling than local ones + // Upstream `DefId` instances get different handling than local ones. if !def_id.is_local() { return if export_generics && is_generic { - // If it is a upstream monomorphization - // and we export generics, we must make + // If it is a upstream monomorphization and we export generics, we must make // it available to downstream crates. *can_be_internalized = false; default_visibility(tcx, def_id, true) @@ -374,20 +373,16 @@ fn mono_item_visibility( if is_generic { if export_generics { if tcx.is_unreachable_local_definition(def_id) { - // This instance cannot be used - // from another crate. + // This instance cannot be used from another crate. Visibility::Hidden } else { - // This instance might be useful in - // a downstream crate. + // This instance might be useful in a downstream crate. *can_be_internalized = false; default_visibility(tcx, def_id, true) } } else { - // We are not exporting generics or - // the definition is not reachable - // for downstream crates, we can - // internalize its instantiations. + // We are not exporting generics or the definition is not reachable + // for downstream crates, we can internalize its instantiations. Visibility::Hidden } } else { @@ -449,19 +444,19 @@ fn default_visibility(tcx: TyCtxt<'_, '_, '_>, id: DefId, is_generic: bool) -> V return Visibility::Default } - // Generic functions never have export level C + // Generic functions never have export-level C. if is_generic { return Visibility::Hidden } // Things with export level C don't get instantiated in - // downstream crates + // downstream crates. if !id.is_local() { return Visibility::Hidden } // C-export level items remain at `Default`, all other internal - // items become `Hidden` + // items become `Hidden`. match tcx.reachable_non_generics(id.krate).get(&id) { Some(SymbolExportLevel::C) => Visibility::Default, _ => Visibility::Hidden, @@ -519,7 +514,7 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< let single_codegen_unit = initial_cgus.len() == 1; for old_codegen_unit in initial_cgus { - // Collect all items that need to be available in this codegen unit + // Collect all items that need to be available in this codegen unit. let mut reachable = FxHashSet::default(); for root in old_codegen_unit.items().keys() { follow_inlining(*root, inlining_map, &mut reachable); @@ -527,10 +522,10 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name().clone()); - // Add all monomorphizations that are not already there + // Add all monomorphizations that are not already there. for mono_item in reachable { if let Some(linkage) = old_codegen_unit.items().get(&mono_item) { - // This is a root, just copy it over + // This is a root, just copy it over. new_codegen_unit.items_mut().insert(mono_item, *linkage); } else { if roots.contains(&mono_item) { @@ -538,7 +533,7 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< {:?}", mono_item); } - // This is a cgu-private copy + // This is a CGU-private copy. new_codegen_unit.items_mut().insert( mono_item, (Linkage::Internal, Visibility::Default), @@ -547,7 +542,7 @@ fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning< if !single_codegen_unit { // If there is more than one codegen unit, we need to keep track - // in which codegen units each monomorphization is placed: + // in which codegen units each monomorphization is placed. match mono_item_placements.entry(mono_item) { Entry::Occupied(e) => { let placement = e.into_mut(); @@ -656,8 +651,8 @@ fn internalize_symbols<'a, 'tcx>(_tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn characteristic_def_id_of_mono_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - mono_item: MonoItem<'tcx>) - -> Option { + mono_item: MonoItem<'tcx>) + -> Option { match mono_item { MonoItem::Fn(instance) => { let def_id = match instance.def { @@ -709,10 +704,10 @@ fn compute_codegen_unit_name(tcx: TyCtxt<'_, '_, '_>, volatile: bool, cache: &mut CguNameCache) -> InternedString { - // Find the innermost module that is not nested within a function + // Find the innermost module that is not nested within a function. let mut current_def_id = def_id; let mut cgu_def_id = None; - // Walk backwards from the item we want to find the module for: + // Walk backwards from the item we want to find the module for. loop { if current_def_id.index == CRATE_DEF_INDEX { if cgu_def_id.is_none() { diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 89c4a9106a477..6a17a84517e4a 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -1,4 +1,4 @@ -// Validate AST before lowering it to HIR +// Validate AST before lowering it to HIR. // // This pass is supposed to catch things that fit into AST data structures, // but not permitted by the language. It runs after expansion when AST is frozen, @@ -56,7 +56,7 @@ struct AstValidator<'a> { /// Used to ban nested `impl Trait`, e.g., `impl Into`. /// Nested `impl Trait` _is_ allowed in associated type position, - /// e.g `impl Iterator` + /// e.g., `impl Iterator`. outer_impl_trait: Option, /// Used to ban `impl Trait` in path projections like `::Item` @@ -94,9 +94,9 @@ impl<'a> AstValidator<'a> { } fn visit_assoc_type_binding_from_generic_args(&mut self, type_binding: &'a TypeBinding) { - // rust-lang/rust#57979: bug in old visit_generic_args called - // walk_ty rather than visit_ty, skipping outer `impl Trait` - // if it happened to occur at `type_binding.ty` + // rust-lang/rust#57979: bug in old `visit_generic_args` called + // `walk_ty` rather than `visit_ty`, skipping outer `impl Trait` + // if it happened to occur at `type_binding.ty`. if let TyKind::ImplTrait(..) = type_binding.ty.node { self.warning_period_57979_didnt_record_next_impl_trait = true; } @@ -104,9 +104,9 @@ impl<'a> AstValidator<'a> { } fn visit_ty_from_generic_args(&mut self, ty: &'a Ty) { - // rust-lang/rust#57979: bug in old visit_generic_args called - // walk_ty rather than visit_ty, skippping outer `impl Trait` - // if it happened to occur at `ty` + // rust-lang/rust#57979: bug in old `visit_generic_args` called + // `walk_ty` rather than `visit_ty`, skippping outer `impl Trait` + // if it happened to occur at `ty`. if let TyKind::ImplTrait(..) = ty.node { self.warning_period_57979_didnt_record_next_impl_trait = true; } @@ -117,10 +117,10 @@ impl<'a> AstValidator<'a> { let only_recorded_since_pull_request_57730 = self.warning_period_57979_didnt_record_next_impl_trait; - // (this flag is designed to be set to true and then only + // (This flag is designed to be set to `true`, and then only // reach the construction point for the outer impl trait once, // so its safe and easiest to unconditionally reset it to - // false) + // false.) self.warning_period_57979_didnt_record_next_impl_trait = false; OuterImplTrait { @@ -128,7 +128,7 @@ impl<'a> AstValidator<'a> { } } - // Mirrors visit::walk_ty, but tracks relevant state + // Mirrors `visit::walk_ty`, but tracks relevant state. fn walk_ty(&mut self, t: &'a Ty) { match t.node { TyKind::ImplTrait(..) => { @@ -619,15 +619,18 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Auto traits cannot have generics, super traits nor contain items. if !generics.params.is_empty() { struct_span_err!(self.session, item.span, E0567, - "auto traits cannot have generic parameters").emit(); + "auto traits cannot have generic parameters" + ).emit(); } if !bounds.is_empty() { struct_span_err!(self.session, item.span, E0568, - "auto traits cannot have super traits").emit(); + "auto traits cannot have super traits" + ).emit(); } if !trait_items.is_empty() { struct_span_err!(self.session, item.span, E0380, - "auto traits cannot have methods or associated items").emit(); + "auto traits cannot have methods or associated items" + ).emit(); } } self.no_questions_in_bounds(bounds, "supertraits", true); @@ -699,7 +702,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_foreign_item(self, fi) } - // Mirrors visit::walk_generic_args, but tracks relevant state + // Mirrors `visit::walk_generic_args`, but tracks relevant state. fn visit_generic_args(&mut self, _: Span, generic_args: &'a GenericArgs) { match *generic_args { GenericArgs::AngleBracketed(ref data) => { @@ -718,7 +721,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { generic_args.span(), ); - // Type bindings such as `Item=impl Debug` in `Iterator` + // Type bindings such as `Item = impl Debug` in `Iterator` // are allowed to contain nested `impl Trait`. self.with_impl_trait(None, |this| { walk_list!(this, visit_assoc_type_binding_from_generic_args, &data.bindings); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 9b9cf80f822b0..fb5c1b1953f08 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2134,7 +2134,7 @@ impl<'a> Resolver<'a> { record_used_id: Option, path_span: Span) -> Option> { - assert!(ns == TypeNS || ns == ValueNS); + assert!(ns == TypeNS || ns == ValueNS); if ident.name == kw::Invalid { return Some(LexicalScopeBinding::Res(Res::Err)); } @@ -2530,10 +2530,12 @@ impl<'a> Resolver<'a> { match item.node { ItemKind::Ty(_, ref generics) | - ItemKind::Fn(_, _, ref generics, _) | - ItemKind::Existential(_, ref generics) => { - self.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), - |this| visit::walk_item(this, item)); + ItemKind::Existential(_, ref generics) | + ItemKind::Fn(_, _, ref generics, _) => { + self.with_generic_param_rib( + HasGenericParams(generics, ItemRibKind), + |this| visit::walk_item(this, item) + ); } ItemKind::Enum(_, ref generics) | @@ -2967,7 +2969,7 @@ impl<'a> Resolver<'a> { binding_map } - // check that all of the arms in an or-pattern have exactly the + // Checks that all of the arms in an or-pattern have exactly the // same set of bindings, with the same binding modes for each. fn check_consistent_bindings(&mut self, pats: &[P]) { if pats.is_empty() { @@ -2987,7 +2989,7 @@ impl<'a> Resolver<'a> { let map_j = self.binding_mode_map(&q); for (&key, &binding_i) in &map_i { if map_j.is_empty() { // Account for missing bindings when - let binding_error = missing_vars // map_j has none. + let binding_error = missing_vars // `map_j` has none. .entry(key.name) .or_insert(BindingError { name: key.name, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index cc054adee7bea..72ac041d2e57d 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -47,14 +47,14 @@ pub trait AstConv<'gcx, 'tcx> { fn get_type_parameter_bounds(&self, span: Span, def_id: DefId) -> &'tcx ty::GenericPredicates<'tcx>; - /// What lifetime should we use when a lifetime is omitted (and not elided)? + /// Returns the lifetime to use when a lifetime is omitted (and not elided). fn re_infer(&self, span: Span, _def: Option<&ty::GenericParamDef>) -> Option>; - /// What type should we use when a type is omitted? + /// Returns the type to use when a type is omitted. fn ty_infer(&self, span: Span) -> Ty<'tcx>; - /// Same as ty_infer, but with a known type parameter definition. + /// Same as `ty_infer`, but with a known type parameter definition. fn ty_infer_for_def(&self, _def: &ty::GenericParamDef, span: Span) -> Ty<'tcx> { @@ -376,8 +376,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } err.emit(); - (provided > required, // `suppress_error` - potential_assoc_types) + ( + provided > required, // `suppress_error` + potential_assoc_types, + ) }; if reported_late_bound_region_err.is_none() @@ -556,7 +558,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } /// Given the type/lifetime/const arguments provided to some path (along with - /// an implicit `Self`, if this is a trait reference) returns the complete + /// an implicit `Self`, if this is a trait reference), returns the complete /// set of substitutions. This may involve applying defaulted type parameters. /// /// Note that the type listing given here is *exactly* what the user provided. @@ -708,8 +710,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { /// are disallowed. Otherwise, they are pushed onto the vector given. pub fn instantiate_mono_trait_ref(&self, trait_ref: &hir::TraitRef, - self_ty: Ty<'tcx>) - -> ty::TraitRef<'tcx> + self_ty: Ty<'tcx> + ) -> ty::TraitRef<'tcx> { self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1); @@ -724,8 +726,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { trait_ref: &hir::TraitRef, self_ty: Ty<'tcx>, poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, - speculative: bool) - -> (ty::PolyTraitRef<'tcx>, Option>) + speculative: bool, + ) -> (ty::PolyTraitRef<'tcx>, Option>) { let trait_def_id = trait_ref.trait_def_id(); @@ -851,13 +853,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // trait SubTrait: SuperTrait { } // trait SuperTrait { type T; } // - // ... B : SubTrait ... + // ... B: SubTrait ... // ``` // // We want to produce `>::T == foo`. // Find any late-bound regions declared in `ty` that are not - // declared in the trait-ref. These are not wellformed. + // declared in the trait-ref. These are not well-formed. // // Example: // @@ -1716,7 +1718,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let span = path.span; match path.res { Res::Def(DefKind::Existential, did) => { - // Check for desugared impl trait. + // Check for desugared `impl Trait`. assert!(ty::is_impl_trait_defn(tcx, did).is_none()); let item_segment = path.segments.split_last().unwrap(); self.prohibit_generics(item_segment.1); @@ -1767,19 +1769,19 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { &tcx.hir().local_def_id_from_hir_id(hir_id)]; tcx.mk_ty_param(index, tcx.hir().name_by_hir_id(hir_id).as_interned_str()) } - Res::SelfTy(_, Some(def_id)) => { - // `Self` in impl (we know the concrete type). - assert_eq!(opt_self_ty, None); - self.prohibit_generics(&path.segments); - // Try to evaluate any array length constants - self.normalize_ty(span, tcx.at(span).type_of(def_id)) - } Res::SelfTy(Some(_), None) => { // `Self` in trait. assert_eq!(opt_self_ty, None); self.prohibit_generics(&path.segments); tcx.mk_self_type() } + Res::SelfTy(_, Some(def_id)) => { + // `Self` in impl (we know the concrete type). + assert_eq!(opt_self_ty, None); + self.prohibit_generics(&path.segments); + // Try to evaluate any array length constants. + self.normalize_ty(span, tcx.at(span).type_of(def_id)) + } Res::Def(DefKind::AssocTy, def_id) => { debug_assert!(path.segments.len() >= 2); self.prohibit_generics(&path.segments[..path.segments.len() - 2]); @@ -1829,7 +1831,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } hir::TyKind::Rptr(ref region, ref mt) => { let r = self.ast_region_to_region(region, None); - debug!("Ref r={:?}", r); + debug!("ast_ty_to_ty: r={:?}", r); let t = self.ast_ty_to_ty(&mt.ty); tcx.mk_ref(r, ty::TypeAndMut {ty: t, mutbl: mt.mutbl}) } @@ -1856,7 +1858,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { hir::TyKind::Def(item_id, ref lifetimes) => { let did = tcx.hir().local_def_id_from_hir_id(item_id.id); self.impl_trait_ty_to_ty(did, lifetimes) - }, + } hir::TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => { debug!("ast_ty_to_ty: qself={:?} segment={:?}", qself, segment); let ty = self.ast_ty_to_ty(qself); @@ -1889,9 +1891,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // handled specially and will not descend into this routine. self.ty_infer(ast_ty.span) } - hir::TyKind::Err => { - tcx.types.err - } hir::TyKind::CVarArgs(lt) => { let va_list_did = match tcx.lang_items().va_list() { Some(did) => did, @@ -1901,6 +1900,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let region = self.ast_region_to_region(<, None); tcx.type_of(va_list_did).subst(tcx, &[region.into()]) } + hir::TyKind::Err => { + tcx.types.err + } }; self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span); @@ -1979,7 +1981,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { _ => bug!() } } else { - // Replace all parent lifetimes with 'static. + // Replace all parent lifetimes with `'static`. match param.kind { GenericParamDefKind::Lifetime => { tcx.lifetimes.re_static.into() diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index d64be24f7538f..aab873323f91e 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -173,7 +173,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> { // here, we would coerce from `!` to `?T`. let b = self.shallow_resolve(b); return if self.shallow_resolve(b).is_ty_var() { - // micro-optimization: no need for this if `b` is + // Micro-optimization: no need for this if `b` is // already resolved in some way. let diverging_ty = self.next_diverging_ty_var( TypeVariableOrigin::AdjustmentType(self.cause.span)); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3ada80b3e8b70..d165c7e2b2cf7 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -518,10 +518,10 @@ pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { /// eventually). param_env: ty::ParamEnv<'tcx>, - // Number of errors that had been reported when we started - // checking this function. On exit, if we find that *more* errors - // have been reported, we will skip regionck and other work that - // expects the types within the function to be consistent. + /// Number of errors that had been reported when we started + /// checking this function. On exit, if we find that *more* errors + /// have been reported, we will skip regionck and other work that + /// expects the types within the function to be consistent. err_count_on_creation: usize, ret_coercion: Option>>, diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 6f8682e64671c..1bc7119b314e9 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -450,38 +450,38 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { let generics = self.tcx().generics_of(def_id); let definition_ty = if generics.parent.is_some() { - // impl trait + // `impl Trait` self.fcx.infer_opaque_definition_from_instantiation( def_id, opaque_defn, instantiated_ty, ) } else { - // prevent + // Prevent: // * `fn foo() -> Foo` // * `fn foo() -> Foo` - // from being defining + // from being defining. // Also replace all generic params with the ones from the existential type - // definition so + // definition so that // ```rust // existential type Foo: 'static; // fn foo() -> Foo { .. } // ``` - // figures out the concrete type with `U`, but the stored type is with `T` + // figures out the concrete type with `U`, but the stored type is with `T`. instantiated_ty.fold_with(&mut BottomUpFolder { tcx: self.tcx().global_tcx(), ty_op: |ty| { trace!("checking type {:?}", ty); - // find a type parameter + // Find a type parameter. if let ty::Param(..) = ty.sty { - // look it up in the substitution list + // Look it up in the substitution list. assert_eq!(opaque_defn.substs.len(), generics.params.len()); for (subst, param) in opaque_defn.substs.iter().zip(&generics.params) { if let UnpackedKind::Type(subst) = subst.unpack() { if subst == ty { - // found it in the substitution list, replace with the - // parameter from the existential type + // Found it in the substitution list; replace with the + // parameter from the existential type. return self.tcx() .global_tcx() .mk_ty_param(param.index, param.name); @@ -505,16 +505,15 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { }, lt_op: |region| { match region { - // Skip static and bound regions: they don't - // require substitution. + // Skip static and bound regions: they don't require substitution. ty::ReStatic | ty::ReLateBound(..) => region, _ => { trace!("checking {:?}", region); for (subst, p) in opaque_defn.substs.iter().zip(&generics.params) { if let UnpackedKind::Lifetime(subst) = subst.unpack() { if subst == region { - // found it in the substitution list, replace with the - // parameter from the existential type + // Found it in the substitution list; replace with the + // parameter from the existential type. let reg = ty::EarlyBoundRegion { def_id: p.def_id, index: p.index, @@ -586,8 +585,8 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> { if let ty::Opaque(defin_ty_def_id, _substs) = definition_ty.sty { if def_id == defin_ty_def_id { - // Concrete type resolved to the existential type itself - // Force a cycle error + // Concrete type resolved to the existential type itself. + // Force a cycle error. // FIXME(oli-obk): we could just not insert it into `concrete_existential_types` // which simply would make this use not a defining use. self.tcx().at(span).type_of(defin_ty_def_id); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 3034cacf6253f..f362263c16e75 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1,6 +1,6 @@ //! "Collection" is the process of determining the type and other external //! details of each item in Rust. Collection is specifically concerned -//! with *interprocedural* things -- for example, for a function +//! with *inter-procedural* things -- for example, for a function //! definition, collection will figure out the type and signature of the //! function, but it will not visit the *body* of the function in any way, //! nor examine type annotations on local variables (that's the job of @@ -233,7 +233,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { } fn set_tainted_by_errors(&self) { - // no obvious place to track this, just let it go + // no obvious place to track this, so just let it go } fn record_ty(&self, _hir_id: hir::HirId, _ty: Ty<'tcx>, _span: Span) { @@ -447,7 +447,7 @@ fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: hir::HirId) { } } - // Desugared from `impl Trait` -> visited by the function's return type + // Desugared from `impl Trait`, so visited by the function's return type. hir::ItemKind::Existential(hir::ExistTy { impl_trait_fn: Some(_), .. @@ -1218,7 +1218,7 @@ pub fn checked_type_of<'a, 'tcx>( impl_trait_fn: None, .. }) => find_existential_constraints(tcx, def_id), - // existential types desugared from impl Trait + // Existential types desugared from `impl Trait`. ItemKind::Existential(hir::ExistTy { impl_trait_fn: Some(owner), .. @@ -1472,11 +1472,13 @@ fn find_existential_constraints<'a, 'tcx>( ) -> Ty<'tcx> { use rustc::hir::{ImplItem, Item, TraitItem}; + debug!("find_existential_constraints({:?})", def_id); + struct ConstraintLocator<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, - // First found type span, actual type, mapping from the existential type's generic - // parameters to the concrete type's generic parameters + // (first found type span, actual type, mapping from the existential type's generic + // parameters to the concrete type's generic parameters) // // The mapping is an index for each use site of a generic parameter in the concrete type // @@ -1502,18 +1504,21 @@ fn find_existential_constraints<'a, 'tcx>( let span = self.tcx.def_span(def_id); // used to quickly look up the position of a generic parameter let mut index_map: FxHashMap = FxHashMap::default(); - // skip binder is ok, since we only use this to find generic parameters and their - // positions. + // Skipping binder is ok, since we only use this to find generic parameters and + // their positions. for (idx, subst) in substs.iter().enumerate() { if let UnpackedKind::Type(ty) = subst.unpack() { if let ty::Param(p) = ty.sty { if index_map.insert(p, idx).is_some() { - // there was already an entry for `p`, meaning a generic parameter - // was used twice + // There was already an entry for `p`, meaning a generic parameter + // was used twice. self.tcx.sess.span_err( span, - &format!("defining existential type use restricts existential \ - type by using the generic parameter `{}` twice", p.name), + &format!( + "defining existential type use restricts existential \ + type by using the generic parameter `{}` twice", + p.name + ), ); return; } @@ -1528,8 +1533,8 @@ fn find_existential_constraints<'a, 'tcx>( } } } - // compute the index within the existential type for each generic parameter used in - // the concrete type + // Compute the index within the existential type for each generic parameter used in + // the concrete type. let indices = concrete_type .subst(self.tcx, substs) .walk() @@ -1607,7 +1612,7 @@ fn find_existential_constraints<'a, 'tcx>( } fn visit_item(&mut self, it: &'tcx Item) { let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id); - // the existential type itself or its children are not within its reveal scope + // The existential type itself or its children are not within its reveal scope. if def_id != self.def_id { self.check(def_id); intravisit::walk_item(self, it); @@ -1615,7 +1620,7 @@ fn find_existential_constraints<'a, 'tcx>( } fn visit_impl_item(&mut self, it: &'tcx ImplItem) { let def_id = self.tcx.hir().local_def_id_from_hir_id(it.hir_id); - // the existential type itself or its children are not within its reveal scope + // The existential type itself or its children are not within its reveal scope. if def_id != self.def_id { self.check(def_id); intravisit::walk_impl_item(self, it); @@ -1960,7 +1965,7 @@ fn explicit_predicates_of<'a, 'tcx>( let substs = InternalSubsts::identity_for_item(tcx, def_id); let opaque_ty = tcx.mk_opaque(def_id, substs); - // Collect the bounds, i.e., the `A+B+'c` in `impl A+B+'c`. + // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`. let bounds = compute_bounds( &icx, opaque_ty, @@ -2006,7 +2011,7 @@ fn explicit_predicates_of<'a, 'tcx>( let substs = InternalSubsts::identity_for_item(tcx, def_id); let opaque_ty = tcx.mk_opaque(def_id, substs); - // Collect the bounds, i.e., the `A+B+'c` in `impl A+B+'c`. + // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`. let bounds = compute_bounds( &icx, opaque_ty, @@ -2016,7 +2021,7 @@ fn explicit_predicates_of<'a, 'tcx>( ); if impl_trait_fn.is_some() { - // impl Trait + // opaque types return tcx.arena.alloc(ty::GenericPredicates { parent: None, predicates: bounds.predicates(tcx, opaque_ty), @@ -2093,7 +2098,7 @@ fn explicit_predicates_of<'a, 'tcx>( } // Collect the predicates that were written inline by the user on each - // type parameter (e.g., ``). + // type parameter (e.g., ``). for param in &ast_generics.params { if let GenericParamKind::Type { .. } = param.kind { let name = param.name.ident().as_interned_str(); @@ -2106,7 +2111,7 @@ fn explicit_predicates_of<'a, 'tcx>( } } - // Add in the bounds that appear in the where-clause + // Add in the bounds that appear in the where-clause. let where_clause = &ast_generics.where_clause; for predicate in &where_clause.predicates { match predicate { @@ -2422,7 +2427,7 @@ fn from_target_feature( continue; } - // Must be of the form `enable = "..."` ( a string) + // Must be of the form `enable = "..."` (a string). let value = match item.value_str() { Some(value) => value, None => { @@ -2545,7 +2550,7 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen if tcx.is_foreign_item(id) { codegen_fn_attrs.flags |= CodegenFnAttrFlags::FFI_RETURNS_TWICE; } else { - // `#[ffi_returns_twice]` is only allowed `extern fn`s + // `#[ffi_returns_twice]` is only allowed `extern fn`s. struct_span_err!( tcx.sess, attr.span, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 95f7c2949cb56..024d73ff65bd2 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -379,8 +379,8 @@ pub fn check_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) /// A quasi-deprecated helper used in rustdoc and clippy to get /// the type from a HIR node. pub fn hir_ty_to_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_ty: &hir::Ty) -> Ty<'tcx> { - // In case there are any projections etc, find the "environment" - // def-id that will be used to determine the traits/predicates in + // In case there are any projections, etc., find the "environment" + // def-ID that will be used to determine the traits/predicates in // scope. This is derived from the enclosing item-like thing. let env_node_id = tcx.hir().get_parent_item(hir_ty.hir_id); let env_def_id = tcx.hir().local_def_id_from_hir_id(env_node_id); @@ -391,8 +391,8 @@ pub fn hir_ty_to_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_ty: &hir::Ty) -> pub fn hir_trait_to_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_trait: &hir::TraitRef) -> (ty::PolyTraitRef<'tcx>, Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>) { - // In case there are any projections etc, find the "environment" - // def-id that will be used to determine the traits/predicates in + // In case there are any projections, etc., find the "environment" + // def-ID that will be used to determine the traits/predicates in // scope. This is derived from the enclosing item-like thing. let env_hir_id = tcx.hir().get_parent_item(hir_trait.hir_ref_id); let env_def_id = tcx.hir().local_def_id_from_hir_id(env_hir_id); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0c00b3b20b5b3..f19e5180939ba 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2443,12 +2443,12 @@ pub struct PolyTrait { pub generic_params: Vec, } -/// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original -/// type out of the AST/TyCtxt given one of these, if more information is needed. Most importantly -/// it does not preserve mutability or boxes. +/// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original +/// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most +/// importantly, it does not preserve mutability or boxes. #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] pub enum Type { - /// Structs/enums/traits (most that'd be an `hir::TyKind::Path`). + /// Structs/enums/traits (most that would be an `hir::TyKind::Path`). ResolvedPath { path: Path, param_names: Option>, @@ -2462,7 +2462,7 @@ pub enum Type { /// Primitives are the fixed-size numeric types (plus int/usize/float), char, /// arrays, slices, and tuples. Primitive(PrimitiveType), - /// extern "ABI" fn + /// `extern "ABI" fn` BareFunction(Box), Tuple(Vec), Slice(Box), @@ -2477,17 +2477,17 @@ pub enum Type { type_: Box, }, - // ::Name + // `::Name` QPath { name: String, self_type: Box, trait_: Box }, - // _ + // `_` Infer, - // impl TraitA+TraitB + // `impl TraitA + TraitB + ...` ImplTrait(Vec), } @@ -2747,7 +2747,6 @@ impl Clean for hir::Ty { match self.node { TyKind::Never => Never, - TyKind::CVarArgs(_) => CVarArgs, TyKind::Ptr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)), TyKind::Rptr(ref l, ref m) => { let lifetime = if l.is_elided() { @@ -2933,12 +2932,13 @@ impl Clean for hir::Ty { } ResolvedPath { path, param_names: Some(bounds), did, is_generic, } } - _ => Infer // shouldn't happen + _ => Infer, // shouldn't happen } } TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)), TyKind::Infer | TyKind::Err => Infer, TyKind::Typeof(..) => panic!("Unimplemented type {:?}", self.node), + TyKind::CVarArgs(_) => CVarArgs, } } } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 1b38d4879050e..38cde12100056 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -18,7 +18,6 @@ use crate::core::DocAccessLevels; use crate::html::item_type::ItemType; use crate::html::render::{self, cache, CURRENT_LOCATION_KEY}; - /// Helper to render an optional visibility with a space after it (if the /// visibility is preset) #[derive(Copy, Clone)] @@ -561,7 +560,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> if param_names.is_some() { f.write_str("dyn ")?; } - // Paths like T::Output and Self::Output should be rendered with all segments + // Paths like `T::Output` and `Self::Output` should be rendered with all segments. resolved_path(f, did, path, is_generic, use_absolute)?; tybounds(f, param_names) } @@ -585,7 +584,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> &[] => primitive_link(f, PrimitiveType::Unit, "()"), &[ref one] => { primitive_link(f, PrimitiveType::Tuple, "(")?; - //carry f.alternate() into this display w/o branching manually + // Carry `f.alternate()` into this display w/o branching manually. fmt::Display::fmt(one, f)?; primitive_link(f, PrimitiveType::Tuple, ",)") } @@ -638,7 +637,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> "&".to_string() }; match **ty { - clean::Slice(ref bt) => { // BorrowedRef{ ... Slice(T) } is &[T] + clean::Slice(ref bt) => { // `BorrowedRef{ ... Slice(T) }` is `&[T]` match **bt { clean::Generic(_) => { if f.alternate() { diff --git a/src/libstd/panicking.rs b/src/libstd/panicking.rs index 27b8a110ca71e..9ef42063f9412 100644 --- a/src/libstd/panicking.rs +++ b/src/libstd/panicking.rs @@ -171,7 +171,8 @@ fn default_hook(info: &PanicInfo<'_>) { } }; - let location = info.location().unwrap(); // The current implementation always returns Some + // The current implementation always returns `Some`. + let location = info.location().unwrap(); let msg = match info.payload().downcast_ref::<&'static str>() { Some(s) => *s, @@ -196,7 +197,7 @@ fn default_hook(info: &PanicInfo<'_>) { if let Some(format) = log_backtrace { let _ = backtrace::print(err, format); } else if FIRST_PANIC.compare_and_swap(true, false, Ordering::SeqCst) { - let _ = writeln!(err, "note: Run with `RUST_BACKTRACE=1` \ + let _ = writeln!(err, "note: run with `RUST_BACKTRACE=1` \ environment variable to display a backtrace."); } } diff --git a/src/libstd/sys_common/backtrace.rs b/src/libstd/sys_common/backtrace.rs index a01b31e948b4e..bf37ff7ddbd3a 100644 --- a/src/libstd/sys_common/backtrace.rs +++ b/src/libstd/sys_common/backtrace.rs @@ -173,7 +173,7 @@ impl<'a, 'b> Printer<'a, 'b> { Some(symbol) => { match self.format { PrintFormat::Full => write!(self.out, "{}", symbol)?, - // strip the trailing hash if short mode + // Strip the trailing hash if short mode. PrintFormat::Short => write!(self.out, "{:#}", symbol)?, } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b8a10d90c3c0a..31e898048003d 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -213,7 +213,7 @@ pub struct ParenthesizedArgs { /// Overall span pub span: Span, - /// `(A,B)` + /// `(A, B)` pub inputs: Vec>, /// `C` @@ -1840,7 +1840,7 @@ impl Arg { } } -/// Header (not the body) of a function declaration. +/// A header (not the body) of a function declaration. /// /// E.g., `fn foo(bar: baz)`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 47c79f8466a95..435a3d7b6a22a 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -10,7 +10,7 @@ use rustc_target::spec::abi::Abi; use syntax_pos::{Pos, Span}; pub trait AstBuilder { - // paths + // Paths fn path(&self, span: Span, strs: Vec ) -> ast::Path; fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path; fn path_global(&self, span: Span, strs: Vec ) -> ast::Path; @@ -69,7 +69,7 @@ pub trait AstBuilder { bounds: ast::GenericBounds) -> ast::GenericParam; - // statements + // Statements fn stmt_expr(&self, expr: P) -> ast::Stmt; fn stmt_semi(&self, expr: P) -> ast::Stmt; fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P) -> ast::Stmt; @@ -83,11 +83,11 @@ pub trait AstBuilder { fn stmt_let_type_only(&self, span: Span, ty: P) -> ast::Stmt; fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt; - // blocks + // Blocks fn block(&self, span: Span, stmts: Vec) -> P; fn block_expr(&self, expr: P) -> P; - // expressions + // Expressions fn expr(&self, span: Span, node: ast::ExprKind) -> P; fn expr_path(&self, path: ast::Path) -> P; fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P; @@ -194,12 +194,12 @@ pub trait AstBuilder { fn lambda_stmts_1(&self, span: Span, stmts: Vec, ident: ast::Ident) -> P; - // items + // Items fn item(&self, span: Span, name: Ident, attrs: Vec , node: ast::ItemKind) -> P; fn arg(&self, span: Span, name: Ident, ty: P) -> ast::Arg; - // FIXME unused self + // FIXME: unused `self` fn fn_decl(&self, inputs: Vec , output: ast::FunctionRetTy) -> P; fn item_fn_poly(&self, @@ -552,7 +552,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - // Generate `let _: Type;`, usually used for type assertions. + // Generates `let _: Type;`, which is usually used for type assertions. fn stmt_let_type_only(&self, span: Span, ty: P) -> ast::Stmt { let local = P(ast::Local { pat: self.pat_wild(span), @@ -606,7 +606,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr(path.span, ast::ExprKind::Path(None, path)) } - /// Constructs a QPath expression. + /// Constructs a `QPath` expression. fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P { self.expr(span, ast::ExprKind::Path(Some(qself), path)) } @@ -736,7 +736,6 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr(sp, ast::ExprKind::Cast(expr, ty)) } - fn expr_some(&self, sp: Span, expr: P) -> P { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); self.expr_call_global(sp, some, vec![expr]) @@ -748,12 +747,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.expr_path(none) } - fn expr_break(&self, sp: Span) -> P { self.expr(sp, ast::ExprKind::Break(None, None)) } - fn expr_tuple(&self, sp: Span, exprs: Vec>) -> P { self.expr(sp, ast::ExprKind::Tup(exprs)) } @@ -797,22 +794,22 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let binding_pat = self.pat_ident(sp, binding_variable); let binding_expr = self.expr_ident(sp, binding_variable); - // Ok(__try_var) pattern + // `Ok(__try_var)` pattern let ok_pat = self.pat_tuple_struct(sp, ok_path, vec![binding_pat.clone()]); - // Err(__try_var) (pattern and expression resp.) + // `Err(__try_var)` (pattern and expression respectively) let err_pat = self.pat_tuple_struct(sp, err_path.clone(), vec![binding_pat]); let err_inner_expr = self.expr_call(sp, self.expr_path(err_path), vec![binding_expr.clone()]); - // return Err(__try_var) + // `return Err(__try_var)` let err_expr = self.expr(sp, ast::ExprKind::Ret(Some(err_inner_expr))); - // Ok(__try_var) => __try_var + // `Ok(__try_var) => __try_var` let ok_arm = self.arm(sp, vec![ok_pat], binding_expr); - // Err(__try_var) => return Err(__try_var) + // `Err(__try_var) => return Err(__try_var)` let err_arm = self.arm(sp, vec![err_pat], err_expr); - // match head { Ok() => ..., Err() => ... } + // `match head { Ok() => ..., Err() => ... }` self.expr_match(sp, head, vec![ok_arm, err_arm]) } @@ -972,7 +969,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - // FIXME unused self + // FIXME: unused `self` fn fn_decl(&self, inputs: Vec, output: ast::FunctionRetTy) -> P { P(ast::FnDecl { inputs, diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 39fcd29e1b084..abfce660c8041 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -191,24 +191,24 @@ enum PrevTokenKind { Other, } -/* ident is handled by common.rs */ +// NOTE: `Ident`s are handled by `common.rs`. #[derive(Clone)] pub struct Parser<'a> { pub sess: &'a ParseSess, - /// the current token: + /// The current token. pub token: token::Token, - /// the span of the current token: + /// The span of the current token. pub span: Span, - /// the span of the previous token: meta_var_span: Option, + /// The span of the previous token. pub prev_span: Span, - /// the previous token kind + /// The kind of the previous troken. prev_token_kind: PrevTokenKind, restrictions: Restrictions, - /// Used to determine the path to externally loaded source files + /// Used to determine the path to externally loaded source files. crate directory: Directory<'a>, - /// Whether to parse sub-modules in other files. + /// `true` to parse sub-modules in other files. pub recurse_into_file_modules: bool, /// Name of the root module this parser originated from. If `None`, then the /// name is not known. This does not change while the parser is descending @@ -217,7 +217,7 @@ pub struct Parser<'a> { crate expected_tokens: Vec, crate token_cursor: TokenCursor, desugar_doc_comments: bool, - /// Whether we should configure out of line modules as we parse. + /// `true` we should configure out of line modules as we parse. pub cfg_mods: bool, /// This field is used to keep track of how many left angle brackets we have seen. This is /// required in order to detect extra leading left angle brackets (`<` characters) and error @@ -2680,8 +2680,7 @@ impl<'a> Parser<'a> { } } - // parse a stream of tokens into a list of TokenTree's, - // up to EOF. + /// Parses a stream of tokens into a list of `TokenTree`s, up to EOF. pub fn parse_all_token_trees(&mut self) -> PResult<'a, Vec> { let mut tts = Vec::new(); while self.token != token::Eof { @@ -5344,9 +5343,10 @@ impl<'a> Parser<'a> { // Parse optional `for<'a, 'b>`. // This `for` is parsed greedily and applies to the whole predicate, // the bounded type can have its own `for` applying only to it. - // Example 1: for<'a> Trait1<'a>: Trait2<'a /*ok*/> - // Example 2: (for<'a> Trait1<'a>): Trait2<'a /*not ok*/> - // Example 3: for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /*ok*/, 'b /*not ok*/> + // Examples: + // * `for<'a> Trait1<'a>: Trait2<'a /* ok */>` + // * `(for<'a> Trait1<'a>): Trait2<'a /* not ok */>` + // * `for<'a> for<'b> Trait1<'a, 'b>: Trait2<'a /* ok */, 'b /* not ok */>` let lifetime_defs = self.parse_late_bound_lifetime_defs()?; // Parse type with mandatory colon and (possibly empty) bounds, @@ -5478,17 +5478,17 @@ impl<'a> Parser<'a> { this.look_ahead(n + 1, |t| t != &token::ModSep) }; - // Parse optional self parameter of a method. - // Only a limited set of initial token sequences is considered self parameters, anything + // Parse optional `self` parameter of a method. + // Only a limited set of initial token sequences is considered `self` parameters; anything // else is parsed as a normal function parameter list, so some lookahead is required. let eself_lo = self.span; let (eself, eself_ident, eself_hi) = match self.token { token::BinOp(token::And) => { - // &self - // &mut self - // &'lt self - // &'lt mut self - // ¬_self + // `&self` + // `&mut self` + // `&'lt self` + // `&'lt mut self` + // `¬_self` (if isolated_self(self, 1) { self.bump(); SelfKind::Region(None, Mutability::Immutable) @@ -5514,10 +5514,10 @@ impl<'a> Parser<'a> { }, expect_ident(self), self.prev_span) } token::BinOp(token::Star) => { - // *self - // *const self - // *mut self - // *not_self + // `*self` + // `*const self` + // `*mut self` + // `*not_self` // Emit special error for `self` cases. let msg = "cannot pass `self` by raw pointer"; (if isolated_self(self, 1) { @@ -5540,8 +5540,8 @@ impl<'a> Parser<'a> { } token::Ident(..) => { if isolated_self(self, 0) { - // self - // self: TYPE + // `self` + // `self: TYPE` let eself_ident = expect_ident(self); let eself_hi = self.prev_span; (if self.eat(&token::Colon) { @@ -5552,8 +5552,8 @@ impl<'a> Parser<'a> { }, eself_ident, eself_hi) } else if self.token.is_keyword(kw::Mut) && isolated_self(self, 1) { - // mut self - // mut self: TYPE + // `mut self` + // `mut self: TYPE` self.bump(); let eself_ident = expect_ident(self); let eself_hi = self.prev_span; @@ -5580,7 +5580,7 @@ impl<'a> Parser<'a> { { self.expect(&token::OpenDelim(token::Paren))?; - // Parse optional self argument + // Parse optional self argument. let self_arg = self.parse_self_arg()?; // Parse the rest of the function parameter list. diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index b81dc53ef6836..44e1f5398d3e0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1715,7 +1715,7 @@ impl<'a> State<'a> { match els { Some(_else) => { match _else.node { - // "another else-if" + // Another `else if` block. ast::ExprKind::If(ref i, ref then, ref e) => { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; @@ -1725,7 +1725,7 @@ impl<'a> State<'a> { self.print_block(then)?; self.print_else(e.as_ref().map(|e| &**e)) } - // "another else-if-let" + // Another `else if let` block. ast::ExprKind::IfLet(ref pats, ref expr, ref then, ref e) => { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; @@ -1738,14 +1738,14 @@ impl<'a> State<'a> { self.print_block(then)?; self.print_else(e.as_ref().map(|e| &**e)) } - // "final else" + // Final `else` block. ast::ExprKind::Block(ref b, _) => { self.cbox(INDENT_UNIT - 1)?; self.ibox(0)?; self.s.word(" else ")?; self.print_block(b) } - // BLEAH, constraints would be great here + // Constraints would be great here! _ => { panic!("print_if saw if with weird alternative"); } diff --git a/src/libsyntax/ptr.rs b/src/libsyntax/ptr.rs index 9afcb7c4621c9..d577243fb3dcd 100644 --- a/src/libsyntax/ptr.rs +++ b/src/libsyntax/ptr.rs @@ -57,7 +57,8 @@ impl P { { f(*self.ptr) } - /// Equivalent to and_then(|x| x) + + /// Equivalent to `and_then(|x| x)`. pub fn into_inner(self) -> T { *self.ptr } diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index eb516b5c7c62f..ba57055b8e009 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -499,7 +499,7 @@ pub fn walk_generic_param<'a, V: Visitor<'a>>(visitor: &mut V, param: &'a Generi walk_list!(visitor, visit_attribute, param.attrs.iter()); walk_list!(visitor, visit_param_bound, ¶m.bounds); match param.kind { - GenericParamKind::Lifetime => {} + GenericParamKind::Lifetime => (), GenericParamKind::Type { ref default } => walk_list!(visitor, visit_ty, default), GenericParamKind::Const { ref ty, .. } => visitor.visit_ty(ty), } diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 7e3082a87d992..ffec667aba5d3 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -922,8 +922,7 @@ impl<'a> MethodDef<'a> { arg_types: Vec<(Ident, P)>, body: P) -> ast::ImplItem { - - // create the generics that aren't for Self + // Create the generics that aren't for `Self`. let fn_generics = self.generics.to_generics(cx, trait_.span, type_ident, generics); let args = { diff --git a/src/libsyntax_ext/proc_macro_decls.rs b/src/libsyntax_ext/proc_macro_decls.rs index 5b8f4f35f2dd1..de8b689396fb9 100644 --- a/src/libsyntax_ext/proc_macro_decls.rs +++ b/src/libsyntax_ext/proc_macro_decls.rs @@ -245,8 +245,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { // First up, make sure we're checking a bare function. If we're not then // we're just not interested in this item. // - // If we find one, try to locate a `#[proc_macro_derive]` attribute on - // it. + // If we find one, try to locate a `#[proc_macro_derive]` attribute on it. let is_fn = match item.node { ast::ItemKind::Fn(..) => true, _ => false, @@ -259,7 +258,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { if let Some(prev_attr) = found_attr { let msg = if attr.path.segments[0].ident.name == prev_attr.path.segments[0].ident.name { - format!("Only one `#[{}]` attribute is allowed on any given function", + format!("only one `#[{}]` attribute is allowed on any given function", attr.path) } else { format!("`#[{}]` and `#[{}]` attributes cannot both be applied \ @@ -267,7 +266,7 @@ impl<'a> Visitor<'a> for CollectProcMacros<'a> { }; self.handler.struct_span_err(attr.span, &msg) - .span_note(prev_attr.span, "Previous attribute here") + .span_note(prev_attr.span, "previous attribute here") .emit(); return; diff --git a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs index 2e2a77b92ca53..7e819e2b34e38 100644 --- a/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs +++ b/src/test/run-pass-fulldeps/pprust-expr-roundtrip.rs @@ -1,23 +1,21 @@ // ignore-cross-compile - // The general idea of this test is to enumerate all "interesting" expressions and check that -// `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test: +// `parse(print(e)) == e` for all `e`. Here's what's interesting, for the purposes of this test: // -// 1. The test focuses on expression nesting, because interactions between different expression -// types are harder to test manually than single expression types in isolation. +// 1. The test focuses on expression nesting, because interactions between different expression +// types are harder to test manually than single expression types in isolation. // -// 2. The test only considers expressions of at most two nontrivial nodes. So it will check `x + -// x` and `x + (x - x)` but not `(x * x) + (x - x)`. The assumption here is that the correct -// handling of an expression might depend on the expression's parent, but doesn't depend on its -// siblings or any more distant ancestors. +// 2. The test only considers expressions of at most two nontrivial nodes. So it will check `x + +// x` and `x + (x - x)` but not `(x * x) + (x - x)`. The assumption here is that the correct +// handling of an expression might depend on the expression's parent, but doesn't depend on its +// siblings or any more distant ancestors. // -// 3. The test only checks certain expression kinds. The assumption is that similar expression -// types, such as `if` and `while` or `+` and `-`, will be handled identically in the printer -// and parser. So if all combinations of exprs involving `if` work correctly, then combinations +// 3. The test only checks certain expression kinds. The assumption is that similar expression +// types, such as `if` and `while` or `+` and `-`, will be handled identically in the printer +// and parser. So if all combinations of exprs involving `if` work correctly, then combinations // using `while`, `if let`, and so on will likely work as well. - #![feature(rustc_private)] extern crate rustc_data_structures; @@ -155,9 +153,9 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P)) { } -// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed. +// Folders for manipulating the placement of `Paren` nodes. See below for why this is needed. -/// MutVisitor that removes all `ExprKind::Paren` nodes. +/// `MutVisitor` that removes all `ExprKind::Paren` nodes. struct RemoveParens; impl MutVisitor for RemoveParens { @@ -171,7 +169,7 @@ impl MutVisitor for RemoveParens { } -/// MutVisitor that inserts `ExprKind::Paren` nodes around every `Expr`. +/// `MutVisitor` that inserts `ExprKind::Paren` nodes around every `Expr`. struct AddParens; impl MutVisitor for AddParens { @@ -205,8 +203,8 @@ fn run() { // We want to know if `parsed` is structurally identical to `e`, ignoring trivial // differences like placement of `Paren`s or the exact ranges of node spans. - // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s - // everywhere we can, then pretty-print. This should give an unambiguous representation of + // Unfortunately, there is no easy way to make this comparison. Instead, we add `Paren`s + // everywhere we can, then pretty-print. This should give an unambiguous representation of // each `Expr`, and it bypasses nearly all of the parenthesization logic, so we aren't // relying on the correctness of the very thing we're testing. RemoveParens.visit_expr(&mut e); diff --git a/src/test/run-pass/traits/trait-object-auto-dedup.rs b/src/test/run-pass/traits/trait-object-auto-dedup.rs index 98a386e4c6e1d..39d25eb7fe05b 100644 --- a/src/test/run-pass/traits/trait-object-auto-dedup.rs +++ b/src/test/run-pass/traits/trait-object-auto-dedup.rs @@ -1,14 +1,15 @@ // run-pass + #![allow(unused_assignments)] + // Test that duplicate auto trait bounds in trait objects don't create new types. #[allow(unused_assignments)] - use std::marker::Send as SendAlias; // A dummy trait for the non-auto trait. trait Trait {} -// A dummy struct to implement Trait, Send, and . +// A dummy struct to implement `Trait` and `Send`. struct Struct; impl Trait for Struct {} @@ -23,12 +24,12 @@ impl dyn Trait + Send + Send { } fn main() { - // 1. Moving into a variable with more Sends and back. + // 1. Moving into a variable with more `Send`s and back. let mut dyn_trait_send = Box::new(Struct) as Box; let dyn_trait_send_send: Box = dyn_trait_send; dyn_trait_send = dyn_trait_send_send; - // 2. Calling methods with different number of Sends. + // 2. Calling methods with different number of `Send`s. let dyn_trait_send = Box::new(Struct) as Box; takes_dyn_trait_send_send(dyn_trait_send); diff --git a/src/test/ui/existential_types/no_revealing_outside_defining_module.rs b/src/test/ui/existential_types/no_revealing_outside_defining_module.rs index 142f2f6d75169..04793c67b564d 100644 --- a/src/test/ui/existential_types/no_revealing_outside_defining_module.rs +++ b/src/test/ui/existential_types/no_revealing_outside_defining_module.rs @@ -9,7 +9,7 @@ mod boo { } } -// don't actually know the type here +// We don't actually know the type here. fn bomp2() { let _: &str = bomp(); //~ ERROR mismatched types diff --git a/src/test/ui/type/type-alias-bounds.rs b/src/test/ui/type/type-alias-bounds.rs index e2be2b9890251..f3cc5becc6f74 100644 --- a/src/test/ui/type/type-alias-bounds.rs +++ b/src/test/ui/type/type-alias-bounds.rs @@ -1,44 +1,44 @@ -// Test ignored_generic_bounds lint warning about bounds in type aliases +// Test `ignored_generic_bounds` lint warning about bounds in type aliases. // compile-pass #![allow(dead_code)] use std::rc::Rc; -type SVec = Vec; +type SVec = Vec; //~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type S2Vec where T: Send = Vec; //~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] -type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); +type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); //~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] -type WVec<'b, T: 'b+'b> = (&'b u32, Vec); +type WVec<'b, T: 'b + 'b> = (&'b u32, Vec); //~^ WARN bounds on generic parameters are not enforced in type aliases [type_alias_bounds] type W2Vec<'b, T> where T: 'b, T: 'b = (&'b u32, Vec); //~^ WARN where clauses are not enforced in type aliases [type_alias_bounds] -static STATIC : u32 = 0; +static STATIC: u32 = 0; fn foo<'a>(y: &'a i32) { // If any of the bounds above would matter, the code below would be rejected. // This can be seen when replacing the type aliases above by newtype structs. // (The type aliases have no unused parameters to make that a valid transformation.) - let mut x : SVec<_> = Vec::new(); + let mut x: SVec<_> = Vec::new(); x.push(Rc::new(42)); // is not send - let mut x : S2Vec<_> = Vec::new(); - x.push(Rc::new(42)); // is not send + let mut x: S2Vec<_> = Vec::new(); + x.push(Rc::new(42)); // is not `Send` - let mut x : VVec<'static, 'a> = (&STATIC, Vec::new()); - x.1.push(y); // 'a: 'static does not hold + let mut x: VVec<'static, 'a> = (&STATIC, Vec::new()); + x.1.push(y); // `'a: 'static` does not hold - let mut x : WVec<'static, &'a i32> = (&STATIC, Vec::new()); - x.1.push(y); // &'a i32: 'static does not hold + let mut x: WVec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold - let mut x : W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); - x.1.push(y); // &'a i32: 'static does not hold + let mut x: W2Vec<'static, &'a i32> = (&STATIC, Vec::new()); + x.1.push(y); // `&'a i32: 'static` does not hold } -// Bounds are not checked either, i.e., the definition is not necessarily well-formed +// Bounds are not checked either; i.e., the definition is not necessarily well-formed. struct Sendable(T); type MySendable = Sendable; // no error here! @@ -47,9 +47,9 @@ trait Bound { type Assoc; } type T1 = U::Assoc; //~ WARN not enforced in type aliases type T2 where U: Bound = U::Assoc; //~ WARN not enforced in type aliases -// This errors -// type T3 = U::Assoc; -// Do this instead +// This errors: +// `type T3 = U::Assoc;` +// Do this instead: type T4 = ::Assoc; // Make sure the help about associatd types is not shown incorrectly diff --git a/src/test/ui/type/type-alias-bounds.stderr b/src/test/ui/type/type-alias-bounds.stderr index 3cc844365fdd0..c0ff56d5ec038 100644 --- a/src/test/ui/type/type-alias-bounds.stderr +++ b/src/test/ui/type/type-alias-bounds.stderr @@ -1,8 +1,18 @@ +warning: duplicate auto trait `::marker[0]::Send[0]` found in type parameter bounds + --> $DIR/type-alias-bounds.rs:8:14 + | +LL | type SVec = Vec; + | ^^^^ ^^^^ subsequent use of auto trait + | | + | first use of auto trait + | + = note: #[warn(duplicate_auto_traits_in_bounds)] on by default + warning: bounds on generic parameters are not enforced in type aliases --> $DIR/type-alias-bounds.rs:8:14 | -LL | type SVec = Vec; - | ^^^^ ^^^^ +LL | type SVec = Vec; + | ^^^^ ^^^^ | = note: #[warn(type_alias_bounds)] on by default = help: the bound will not be checked when the type alias is used, and should be removed @@ -18,16 +28,16 @@ LL | type S2Vec where T: Send = Vec; warning: bounds on generic parameters are not enforced in type aliases --> $DIR/type-alias-bounds.rs:12:19 | -LL | type VVec<'b, 'a: 'b+'b> = (&'b u32, Vec<&'a i32>); - | ^^ ^^ +LL | type VVec<'b, 'a: 'b + 'b> = (&'b u32, Vec<&'a i32>); + | ^^ ^^ | = help: the bound will not be checked when the type alias is used, and should be removed warning: bounds on generic parameters are not enforced in type aliases --> $DIR/type-alias-bounds.rs:14:18 | -LL | type WVec<'b, T: 'b+'b> = (&'b u32, Vec); - | ^^ ^^ +LL | type WVec<'b, T: 'b + 'b> = (&'b u32, Vec); + | ^^ ^^ | = help: the bound will not be checked when the type alias is used, and should be removed From dce27cba78ebda2c5adfe149d33af5a88a28d08d Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sun, 17 Mar 2019 15:26:01 +0000 Subject: [PATCH 02/24] Enabled `Self` in type aliases. --- src/librustc_resolve/lib.rs | 12 +++++++++++- src/librustc_typeck/astconv.rs | 2 +- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index fb5c1b1953f08..61a860aef8597 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2529,7 +2529,17 @@ impl<'a> Resolver<'a> { debug!("(resolving item) resolving {} ({:?})", name, item.node); match item.node { - ItemKind::Ty(_, ref generics) | + ItemKind::Ty(_, ref generics) => { + self.with_current_self_item(item, |this| { + this.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { + let item_def_id = this.definitions.local_def_id(item.id); + this.with_self_rib(Def::SelfTy(Some(item_def_id), None), |this| { + visit::walk_item(this, item) + }) + }) + }); + } + ItemKind::Existential(_, ref generics) | ItemKind::Fn(_, _, ref generics, _) => { self.with_generic_param_rib( diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 72ac041d2e57d..f6e3f1a99e831 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1770,7 +1770,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { tcx.mk_ty_param(index, tcx.hir().name_by_hir_id(hir_id).as_interned_str()) } Res::SelfTy(Some(_), None) => { - // `Self` in trait. + // `Self` in trait or type alias. assert_eq!(opt_self_ty, None); self.prohibit_generics(&path.segments); tcx.mk_self_type() From 3816958f18ea6c8990d64d03da839e5a180b0b9b Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 28 Feb 2019 22:43:53 +0000 Subject: [PATCH 03/24] Implemented for function bounds, type bounds, and named existential types. --- src/librustc/hir/lowering.rs | 68 +++++++++----- src/librustc/hir/map/definitions.rs | 5 ++ src/librustc/hir/map/mod.rs | 83 +++++++++++++---- src/librustc/infer/opaque_types/mod.rs | 41 +++++---- src/librustc/traits/select.rs | 3 +- src/librustc_interface/util.rs | 16 +++- src/librustc_passes/ast_validation.rs | 18 ++-- src/librustc_passes/hir_stats.rs | 6 +- src/librustc_typeck/check/wfcheck.rs | 118 ++++++++++++++----------- src/librustc_typeck/collect.rs | 46 +++++++--- src/libsyntax/ast.rs | 28 ++++-- src/libsyntax/ext/build.rs | 16 ++-- src/libsyntax/mut_visit.rs | 23 +++-- src/libsyntax/parse/parser.rs | 52 ++++++----- src/libsyntax/print/pprust.rs | 15 +++- src/libsyntax/util/node_count.rs | 4 +- src/libsyntax/visit.rs | 21 +++-- 17 files changed, 367 insertions(+), 196 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index af8c9c38de5ff..5a0e9d53b0833 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -69,7 +69,7 @@ use syntax::symbol::{kw, sym, Symbol}; use syntax::tokenstream::{TokenStream, TokenTree}; use syntax::parse::token::Token; use syntax::visit::{self, Visitor}; -use syntax_pos::{edition, Span}; +use syntax_pos::{DUMMY_SP, edition, Span}; const HIR_ID_COUNTER_LOCKED: u32 = 0xFFFFFFFF; @@ -191,9 +191,9 @@ enum ImplTraitContext<'a> { /// equivalent to a fresh existential parameter like `existential type T; fn foo() -> T`. /// /// We optionally store a `DefId` for the parent item here so we can look up necessary - /// information later. It is `None` when no information about the context should be stored, - /// e.g., for consts and statics. - Existential(Option), + /// information later. It is `None` when no information about the context should be stored + /// (e.g., for consts and statics). + Existential(Option /* fn def-ID */), /// `impl Trait` is not accepted in this position. Disallowed(ImplTraitPosition), @@ -216,7 +216,7 @@ impl<'a> ImplTraitContext<'a> { use self::ImplTraitContext::*; match self { Universal(params) => Universal(params), - Existential(did) => Existential(*did), + Existential(fn_def_id) => Existential(*fn_def_id), Disallowed(pos) => Disallowed(*pos), } } @@ -1342,13 +1342,36 @@ impl<'a> LoweringContext<'a> { } } - fn lower_ty_binding(&mut self, b: &TypeBinding, - itctx: ImplTraitContext<'_>) -> hir::TypeBinding { + fn lower_assoc_ty_constraint(&mut self, + c: &AssocTyConstraint, + itctx: ImplTraitContext<'_>) + -> hir::TypeBinding { + let ty = match c.kind { + AssocTyConstraintKind::Equality { ref ty } => self.lower_ty(ty, itctx), + AssocTyConstraintKind::Bound { ref bounds } => { + // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. + let impl_ty_node_id = self.sess.next_node_id(); + let parent_def_index = self.current_hir_id_owner.last().unwrap().0; + self.resolver.definitions().create_def_with_parent( + parent_def_index, + impl_ty_node_id, + DefPathData::Misc, + DefIndexAddressSpace::High, + Mark::root(), + DUMMY_SP); + self.lower_ty(&Ty { + id: self.sess.next_node_id(), + node: TyKind::ImplTrait(impl_ty_node_id, bounds.clone()), + span: DUMMY_SP, + }, itctx) + } + }; + hir::TypeBinding { - hir_id: self.lower_node_id(b.id), - ident: b.ident, - ty: self.lower_ty(&b.ty, itctx), - span: b.span, + hir_id: self.lower_node_id(c.id), + ident: c.ident, + ty + span: c.span, } } @@ -1604,7 +1627,7 @@ impl<'a> LoweringContext<'a> { origin: hir::ExistTyOrigin::ReturnImplTrait, }; - trace!("exist ty from impl trait def index: {:#?}", exist_ty_def_index); + trace!("exist ty from impl trait def-index: {:#?}", exist_ty_def_index); let exist_ty_id = lctx.generate_existential_type( exist_ty_node_id, exist_ty_item, @@ -1617,7 +1640,7 @@ impl<'a> LoweringContext<'a> { }) } - /// Registers a new existential type with the proper NodeIds and + /// Registers a new existential type with the proper `NodeId`ss and /// returns the lowered node ID for the existential type. fn generate_existential_type( &mut self, @@ -2195,7 +2218,7 @@ impl<'a> LoweringContext<'a> { param_mode: ParamMode, mut itctx: ImplTraitContext<'_>, ) -> (hir::GenericArgs, bool) { - let &AngleBracketedArgs { ref args, ref bindings, .. } = data; + let &AngleBracketedArgs { ref args, ref constraints, .. } = data; let has_types = args.iter().any(|arg| match arg { ast::GenericArg::Type(_) => true, _ => false, @@ -2203,7 +2226,8 @@ impl<'a> LoweringContext<'a> { ( hir::GenericArgs { args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(), - bindings: bindings.iter().map(|b| self.lower_ty_binding(b, itctx.reborrow())).collect(), + bindings: constraints.iter().map( + |b| self.lower_assoc_ty_constraint(b, itctx.reborrow())).collect(), parenthesized: false, }, !has_types && param_mode == ParamMode::Optional @@ -3236,12 +3260,14 @@ impl<'a> LoweringContext<'a> { self.lower_ty(t, ImplTraitContext::disallowed()), self.lower_generics(generics, ImplTraitContext::disallowed()), ), - ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential(hir::ExistTy { - generics: self.lower_generics(generics, ImplTraitContext::disallowed()), - bounds: self.lower_param_bounds(b, ImplTraitContext::disallowed()), - impl_trait_fn: None, - origin: hir::ExistTyOrigin::ExistentialType, - }), + ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential( + hir::ExistTy { + generics: self.lower_generics(generics, ImplTraitContext::disallowed()), + bounds: self.lower_param_bounds(b, ImplTraitContext::Existential(None)), + impl_trait_fn: None, + origin: hir::ExistTyOrigin::ExistentialType, + }, + ), ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum( hir::EnumDef { variants: enum_definition diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index b85f6f6ce8483..b01eed8f6609d 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -397,6 +397,11 @@ impl Definitions { self.node_to_hir_id[node_id] } + #[inline] + pub fn def_index_to_node_id(&self, def_index: DefIndex) -> ast::NodeId { + self.as_local_node_id(DefId::local(def_index)).unwrap() + } + /// Retrieves the span of the given `DefId` if `DefId` is in the local crate, the span exists /// and it's not `DUMMY_SP`. #[inline] diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 18c596f164dc2..cdbeb8a4a545d 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -288,7 +288,7 @@ impl<'hir> Map<'hir> { #[inline] pub fn def_index_to_node_id(&self, def_index: DefIndex) -> NodeId { - self.definitions.as_local_node_id(DefId::local(def_index)).unwrap() + self.definitions.def_index_to_node_id(def_index) } #[inline] @@ -649,16 +649,16 @@ impl<'hir> Map<'hir> { result } - /// Similar to `get_parent`; returns the parent node-id, or own `id` if there is - /// no parent. Note that the parent may be `CRATE_NODE_ID`, which is not itself - /// present in the map -- so passing the return value of get_parent_node to - /// get may actually panic. - /// This function returns the immediate parent in the AST, whereas get_parent + /// Similar to `get_parent`; returns the parent node-ID, or just `hir_id` if there + /// is no parent. Note that the parent may be `CRATE_NODE_ID`, which is not itself + /// present in the map, so passing the return value of `get_parent_node` to + /// `get` may in fact panic. + /// This function returns the immediate parent in the AST, whereas `get_parent` /// returns the enclosing item. Note that this might not be the actual parent - /// node in the AST - some kinds of nodes are not in the map and these will - /// never appear as the parent_node. So you can always walk the `parent_nodes` - /// from a node to the root of the ast (unless you get the same ID back here - /// that can happen if the ID is not in the map itself or is just weird). + /// node in the AST -- some kinds of nodes are not in the map and these will + /// never appear as the parent node. Thus, you can always walk the parent nodes + /// from a node to the root of the AST (unless you get back the same ID here, + /// which can happen if the ID is not in the map itself or is just weird). pub fn get_parent_node(&self, id: NodeId) -> NodeId { let hir_id = self.node_to_hir_id(id); let parent_hir_id = self.get_parent_node_by_hir_id(hir_id); @@ -841,21 +841,66 @@ impl<'hir> Map<'hir> { } } - /// Returns the nearest enclosing scope. A scope is an item or block. - /// FIXME: it is not clear to me that all items qualify as scopes -- statics - /// and associated types probably shouldn't, for example. Behavior in this - /// regard should be expected to be highly unstable. - pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option { + /// Returns the nearest enclosing scope. A scope is roughly an item or block. + pub fn get_enclosing_scope(&self, id: HirId) -> Option { self.walk_parent_nodes(hir_id, |node| match *node { - Node::Item(_) | - Node::ForeignItem(_) | - Node::TraitItem(_) | - Node::ImplItem(_) | + Node::Item(i) => { + match i.node { + ItemKind::Fn(..) + | ItemKind::Mod(..) + | ItemKind::Enum(..) + | ItemKind::Struct(..) + | ItemKind::Union(..) + | ItemKind::Trait(..) + | ItemKind::Impl(..) => true, + _ => false, + } + }, + Node::ForeignItem(fi) => { + match fi.node { + ForeignItemKind::Fn(..) => true, + _ => false, + } + }, + Node::TraitItem(ti) => { + match ti.node { + TraitItemKind::Method(..) => true, + _ => false, + } + }, + Node::ImplItem(ii) => { + match ii.node { + ImplItemKind::Method(..) => true, + _ => false, + } + }, Node::Block(_) => true, _ => false, }, |_| false).ok() } + /// Returns the defining scope for an existential type definition. + pub fn get_defining_scope(&self, id: NodeId) -> Option { + let mut scope = id; + loop { + scope = self.get_enclosing_scope(scope)?; + if scope == CRATE_NODE_ID { + return Some(CRATE_NODE_ID); + } + match self.get(scope) { + Node::Item(i) => { + match i.node { + ItemKind::Existential(ExistTy { impl_trait_fn: None, .. }) => {} + _ => break, + } + } + Node::Block(_) => {} + _ => break, + } + } + Some(scope) + } + pub fn get_parent_did(&self, id: NodeId) -> DefId { let hir_id = self.node_to_hir_id(id); self.get_parent_did_by_hir_id(hir_id) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 1423b855745e7..ef216110c9e62 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -786,13 +786,13 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { match tcx.hir().find_by_hir_id(opaque_hir_id) { Some(Node::Item(item)) => match item.node { - // impl trait + // Anonymous `impl Trait` hir::ItemKind::Existential(hir::ExistTy { impl_trait_fn: Some(parent), origin, .. }) => (parent == self.parent_def_id, origin), - // named existential types + // Named `existential type` hir::ItemKind::Existential(hir::ExistTy { impl_trait_fn: None, origin, @@ -868,7 +868,7 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { let predicates_of = tcx.predicates_of(def_id); debug!( - "instantiate_opaque_types: predicates: {:#?}", + "instantiate_opaque_types: predicates={:#?}", predicates_of, ); let bounds = predicates_of.instantiate(tcx, substs); @@ -884,11 +884,11 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { // (e.g., `existential type Foo: Bar;` needs to be // defined by a function like `fn foo() -> Foo`). debug!( - "instantiate_opaque_types: param_env: {:#?}", + "instantiate_opaque_types: param_env={:#?}", self.param_env, ); debug!( - "instantiate_opaque_types: generics: {:#?}", + "instantiate_opaque_types: generics={:#?}", tcx.generics_of(def_id), ); @@ -922,8 +922,9 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { } } -/// Returns `true` if `opaque_node_id` is a sibling or a child of a sibling of `def_id`. +/// Returns `true` if `opaque_hir_id` is a sibling or a child of a sibling of `def_id`. /// +/// Example: /// ```rust /// pub mod foo { /// pub mod bar { @@ -936,24 +937,28 @@ impl<'a, 'gcx, 'tcx> Instantiator<'a, 'gcx, 'tcx> { /// } /// ``` /// -/// Here, `def_id` is the `DefId` of the existential type `Baz` and `opaque_node_id` is the -/// `NodeId` of the reference to `Baz` (i.e., the return type of both `f1` and `f2`). -/// We return `true` if the reference is within the same module as the existential type -/// (i.e., `true` for `f1`, `false` for `f2`). +/// Here, `def_id` is the `DefId` of the defining use of the existential type (e.g., `f1` or `f2`), +/// and `opaque_hir_id` is the `HirId` of the definition of the existential type `Baz`. +/// For the above example, this function returns `true` for `f1` and `false` for `f2`. pub fn may_define_existential_type( tcx: TyCtxt<'_, '_, '_>, def_id: DefId, opaque_hir_id: hir::HirId, ) -> bool { let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); - // Named existential types can be defined by any siblings or - // children of siblings. - let mod_id = tcx.hir().get_parent_item(opaque_hir_id); - // We walk up the node tree until we hit the root or the parent - // of the opaque type. - while hir_id != mod_id && node_id != ast::CRATE_HIR_ID { + trace!( + "may_define_existential_type(def={:?}, opaque_node={:?})", + tcx.hir().get(hir_id), + tcx.hir().get(opaque_hir_id) + ); + + // Named existential types can be defined by any siblings or children of siblings. + let scope_id = tcx.hir().get_defining_scope(opaque_hir_id) + .expect("could not get defining scope"); + // We walk up the node tree until we hit the root or the scope of the opaque type. + while hir_id != scope_id && hir_id != ast::CRATE_hir_ID { hir_id = tcx.hir().get_parent_item(hir_id); } - // Syntactically we are allowed to define the concrete type. - hir_id == mod_id + // Syntactically, we are allowed to define the concrete type if: + hir_id == scope_id } diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index fc9756d52f55d..7810d65e88cc1 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -1848,8 +1848,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { .iter() .filter_map(|o| o.to_opt_poly_trait_ref()); - // micro-optimization: filter out predicates relating to different - // traits. + // Micro-optimization: filter out predicates relating to different traits. let matching_bounds = all_bounds.filter(|p| p.def_id() == stack.obligation.predicate.def_id()); diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 4ff996d1f5707..f49f2110f2365 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -716,8 +716,22 @@ impl<'a> ReplaceBodyWithLoop<'a> { ast::GenericArg::Type(ty) => Some(ty), _ => None, }); + let any_assoc_ty_bounds = data.constraints.iter().any(|c| { + if let ast::AssocTyConstraintKind::Bound { .. } = c.kind { + true + } else { + false + } + }); + any_assoc_ty_bounds || any_involves_impl_trait(types.into_iter()) || - any_involves_impl_trait(data.bindings.iter().map(|b| &b.ty)) + any_involves_impl_trait(data.constraints.iter().filter_map(|c| { + if let ast::AssocTyConstraintKind::Equality { ref ty } = c.kind { + Some(ty) + } else { + None + } + })) }, Some(&ast::GenericArgs::Parenthesized(ref data)) => { any_involves_impl_trait(data.inputs.iter()) || diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 6a17a84517e4a..2d602a7f1b468 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -93,14 +93,16 @@ impl<'a> AstValidator<'a> { self.outer_impl_trait = old; } - fn visit_assoc_type_binding_from_generic_args(&mut self, type_binding: &'a TypeBinding) { - // rust-lang/rust#57979: bug in old `visit_generic_args` called - // `walk_ty` rather than `visit_ty`, skipping outer `impl Trait` - // if it happened to occur at `type_binding.ty`. - if let TyKind::ImplTrait(..) = type_binding.ty.node { - self.warning_period_57979_didnt_record_next_impl_trait = true; + fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) { + if let AssocTyConstraintKind::Equality { ref ty } = constraint.kind { + // rust-lang/rust#57979: bug in old `visit_generic_args` called + // `walk_ty` rather than `visit_ty`, skipping outer `impl Trait` + // if it happened to occur at `ty`. + if let TyKind::ImplTrait(..) = ty.node { + self.warning_period_57979_didnt_record_next_impl_trait = true; + } } - self.visit_assoc_type_binding(type_binding); + self.visit_assoc_ty_constraint(constraint); } fn visit_ty_from_generic_args(&mut self, ty: &'a Ty) { @@ -724,7 +726,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Type bindings such as `Item = impl Debug` in `Iterator` // are allowed to contain nested `impl Trait`. self.with_impl_trait(None, |this| { - walk_list!(this, visit_assoc_type_binding_from_generic_args, &data.bindings); + walk_list!(this, visit_assoc_ty_constraint_from_generic_args, &data.constraints); }); } GenericArgs::Parenthesized(ref data) => { diff --git a/src/librustc_passes/hir_stats.rs b/src/librustc_passes/hir_stats.rs index 0088c97679c66..6936aedb9de80 100644 --- a/src/librustc_passes/hir_stats.rs +++ b/src/librustc_passes/hir_stats.rs @@ -353,9 +353,9 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> { ast_visit::walk_path_segment(self, path_span, path_segment) } - fn visit_assoc_type_binding(&mut self, type_binding: &'v ast::TypeBinding) { - self.record("TypeBinding", Id::None, type_binding); - ast_visit::walk_assoc_type_binding(self, type_binding) + fn visit_assoc_ty_constraint(&mut self, constraint: &'v ast::AssocTyConstraint) { + self.record("AssocTyConstraint", Id::None, constraint); + ast_visit::walk_assoc_ty_constraint(self, constraint) } fn visit_attribute(&mut self, attr: &'v ast::Attribute) { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index e11172ae36d9b..2b627a692508e 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -20,8 +20,11 @@ use rustc::hir::itemlikevisit::ParItemLikeVisitor; use rustc::hir; /// Helper type of a temporary returned by `.for_item(...)`. -/// Necessary because we can't write the following bound: -/// `F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>)`. +/// This is necessary because we can't write the following bound: +/// +/// ```rust +/// F: for<'b, 'tcx> where 'gcx: 'tcx FnOnce(FnCtxt<'b, 'gcx, 'tcx>) +/// ``` struct CheckWfFcxBuilder<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { inherited: super::InheritedBuilder<'a, 'gcx, 'tcx>, id: hir::HirId, @@ -42,7 +45,7 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { if !inh.tcx.features().trivial_bounds { // As predicates are cached rather than obligations, this // needsto be called first so that they are checked with an - // empty param_env. + // empty `param_env`. check_false_global_bounds(&fcx, span, id); } let wf_tys = f(&fcx, fcx.tcx.global_tcx()); @@ -56,7 +59,9 @@ impl<'a, 'gcx, 'tcx> CheckWfFcxBuilder<'a, 'gcx, 'tcx> { /// well-formed, meaning that they do not require any constraints not declared in the struct /// definition itself. For example, this definition would be illegal: /// -/// struct Ref<'a, T> { x: &'a T } +/// ```rust +/// struct Ref<'a, T> { x: &'a T } +/// ``` /// /// because the type did not declare that `T:'a`. /// @@ -75,7 +80,7 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def // Right now we check that every default trait implementation // has an implementation of itself. Basically, a case like: // - // `impl Trait for T {}` + // impl Trait for T {} // // has a requirement of `T: Trait` which was required for default // method implementations. Although this could be improved now that @@ -85,7 +90,7 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def // Since there's such a requirement, we need to check *just* positive // implementations, otherwise things like: // - // impl !Send for T {} + // impl !Send for T {} // // won't be allowed unless there's an *explicit* implementation of `Send` // for `T` @@ -98,7 +103,7 @@ pub fn check_item_well_formed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: Def if polarity == hir::ImplPolarity::Positive { check_impl(tcx, item, self_ty, trait_ref); } else { - // FIXME(#27579) what amount of WF checking do we need for neg impls? + // FIXME(#27579): what amount of WF checking do we need for neg impls? if trait_ref.is_some() && !is_auto { span_err!(tcx.sess, item.span, E0192, "negative impls are only allowed for \ @@ -302,7 +307,8 @@ fn check_type_defn<'a, 'tcx, F>(tcx: TyCtxt<'a, 'tcx, 'tcx>, check_where_clauses(tcx, fcx, item.span, def_id, None); - vec![] // no implied bounds in a struct def'n + // No implied bounds in a struct definition. + vec![] }); } @@ -369,7 +375,8 @@ fn check_item_type<'a, 'tcx>( ); } - vec![] // no implied bounds in a const etc + // No implied bounds in a const, etc. + vec![] }); } @@ -421,6 +428,8 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>( def_id: DefId, return_ty: Option>, ) { + debug!("check_where_clauses(def_id={:?}, return_ty={:?})", def_id, return_ty); + let predicates = fcx.tcx.predicates_of(def_id); let generics = tcx.generics_of(def_id); @@ -434,15 +443,17 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>( }; // Check that concrete defaults are well-formed. See test `type-check-defaults.rs`. - // For example this forbids the declaration: - // struct Foo> { .. } - // Here the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold. + // For example, this forbids the declaration: + // + // struct Foo> { .. } + // + // Here, the default `Vec<[u32]>` is not WF because `[u32]: Sized` does not hold. for param in &generics.params { if let GenericParamDefKind::Type { .. } = param.kind { if is_our_default(¶m) { let ty = fcx.tcx.type_of(param.def_id); - // ignore dependent defaults -- that is, where the default of one type - // parameter includes another (e.g., ). In those cases, we can't + // Ignore dependent defaults -- that is, where the default of one type + // parameter includes another (e.g., ``). In those cases, we can't // be sure if it will error or not as user might always specify the other. if !ty.needs_subst() { fcx.register_wf_obligation(ty, fcx.tcx.def_span(param.def_id), @@ -468,16 +479,16 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>( } GenericParamDefKind::Type { .. } => { - // If the param has a default, + // If the param has a default, ... if is_our_default(param) { let default_ty = fcx.tcx.type_of(param.def_id); - // and it's not a dependent default + // ... and it's not a dependent default, ... if !default_ty.needs_subst() { - // then substitute with the default. + // ... then substitute it with the default. return default_ty.into(); } } - // Mark unwanted params as err. + // Mark unwanted params as error. fcx.tcx.types.err.into() } @@ -525,7 +536,7 @@ fn check_where_clauses<'a, 'gcx, 'fcx, 'tcx>( Some(substituted_pred) } }).map(|pred| { - // convert each of those into an obligation. So if you have + // Convert each of those into an obligation. So if you have // something like `struct Foo`, we would // take that predicate `T: Copy`, substitute to `String: Copy` // (actually that happens in the previous `flat_map` call), @@ -595,14 +606,13 @@ fn check_fn_or_method<'a, 'fcx, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'gcx>, /// ```rust /// existential type Foo; /// -/// // ok -- `Foo` is applied to two distinct, generic types. +/// // Okay -- `Foo` is applied to two distinct, generic types. /// fn a() -> Foo { .. } /// -/// // not ok -- `Foo` is applied to `T` twice. +/// // Not okay -- `Foo` is applied to `T` twice. /// fn b() -> Foo { .. } /// -/// -/// // not ok -- `Foo` is applied to a non-generic type. +/// // Not okay -- `Foo` is applied to a non-generic type. /// fn b() -> Foo { .. } /// ``` /// @@ -613,7 +623,7 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( span: Span, ty: Ty<'tcx>, ) -> Vec> { - trace!("check_existential_types: {:?}", ty); + trace!("check_existential_types(ty={:?})", ty); let mut substituted_predicates = Vec::new(); ty.fold_with(&mut ty::fold::BottomUpFolder { tcx: fcx.tcx, @@ -621,17 +631,17 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( if let ty::Opaque(def_id, substs) = ty.sty { trace!("check_existential_types: opaque_ty, {:?}, {:?}", def_id, substs); let generics = tcx.generics_of(def_id); - // only check named existential types defined in this crate + // Only check named existential types defined in this crate. if generics.parent.is_none() && def_id.is_local() { let opaque_hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); if may_define_existential_type(tcx, fn_def_id, opaque_hir_id) { - trace!("check_existential_types may define. Generics: {:#?}", generics); + trace!("check_existential_types: may define, generics={:#?}", generics); let mut seen: FxHashMap<_, Vec<_>> = FxHashMap::default(); for (subst, param) in substs.iter().zip(&generics.params) { match subst.unpack() { ty::subst::UnpackedKind::Type(ty) => match ty.sty { ty::Param(..) => {} - // prevent `fn foo() -> Foo` from being defining + // Prevent `fn foo() -> Foo` from being defining. _ => { tcx.sess .struct_span_err( @@ -713,20 +723,19 @@ fn check_existential_types<'a, 'fcx, 'gcx, 'tcx>( } } // if may_define_existential_type - // now register the bounds on the parameters of the existential type - // so the parameters given by the function need to fulfill them - // ```rust - // existential type Foo: 'static; - // fn foo() -> Foo { .. *} - // ``` + // Now register the bounds on the parameters of the existential type + // so the parameters given by the function need to fulfill them. + // + // existential type Foo: 'static; + // fn foo() -> Foo { .. *} + // // becomes - // ```rust - // existential type Foo: 'static; - // fn foo() -> Foo { .. *} - // ``` + // + // existential type Foo: 'static; + // fn foo() -> Foo { .. *} let predicates = tcx.predicates_of(def_id); trace!( - "check_existential_types may define. adding predicates: {:#?}", + "check_existential_types: may define, predicates={:#?}", predicates, ); for &(pred, _) in predicates.predicates.iter() { @@ -751,7 +760,7 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, method: &ty::AssocItem, self_ty: Ty<'tcx>) { - // check that the method has a valid receiver type, given the type `Self` + // Check that the method has a valid receiver type, given the type `Self`. debug!("check_method_receiver({:?}, self_ty={:?})", method, self_ty); @@ -783,7 +792,7 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, if fcx.tcx.features().arbitrary_self_types { if !receiver_is_valid(fcx, span, receiver_ty, self_ty, true) { - // report error, arbitrary_self_types was enabled + // Report error; `arbitrary_self_types` was enabled. fcx.tcx.sess.diagnostic().mut_span_err( span, &format!("invalid method receiver type: {:?}", receiver_ty) ).note("type of `self` must be `Self` or a type that dereferences to it") @@ -794,7 +803,7 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, } else { if !receiver_is_valid(fcx, span, receiver_ty, self_ty, false) { if receiver_is_valid(fcx, span, receiver_ty, self_ty, true) { - // report error, would have worked with arbitrary_self_types + // Report error; would have worked with `arbitrary_self_types`. feature_gate::feature_err( &fcx.tcx.sess.parse_sess, sym::arbitrary_self_types, @@ -808,7 +817,7 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, ).help("consider changing to `self`, `&self`, `&mut self`, or `self: Box`") .emit(); } else { - // report error, would not have worked with arbitrary_self_types + // Report error; would not have worked with `arbitrary_self_types`. fcx.tcx.sess.diagnostic().mut_span_err( span, &format!("invalid method receiver type: {:?}", receiver_ty) ).note("type must be `Self` or a type that dereferences to it") @@ -820,10 +829,11 @@ fn check_method_receiver<'fcx, 'gcx, 'tcx>(fcx: &FnCtxt<'fcx, 'gcx, 'tcx>, } } -/// returns true if `receiver_ty` would be considered a valid receiver type for `self_ty`. If +/// Returns whether `receiver_ty` would be considered a valid receiver type for `self_ty`. If /// `arbitrary_self_types` is enabled, `receiver_ty` must transitively deref to `self_ty`, possibly /// through a `*const/mut T` raw pointer. If the feature is not enabled, the requirements are more -/// strict: `receiver_ty` must implement `Receiver` and directly implement `Deref`. +/// strict: `receiver_ty` must implement `Receiver` and directly implement +/// `Deref`. /// /// N.B., there are cases this function returns `true` but causes an error to be emitted, /// particularly when `receiver_ty` derefs to a type that is the same as `self_ty` but has the @@ -839,7 +849,7 @@ fn receiver_is_valid<'fcx, 'tcx, 'gcx>( let can_eq_self = |ty| fcx.infcx.can_eq(fcx.param_env, self_ty, ty).is_ok(); - // `self: Self` is always valid + // `self: Self` is always valid. if can_eq_self(receiver_ty) { if let Some(mut err) = fcx.demand_eqtype_with_origin(&cause, self_ty, receiver_ty) { err.emit(); @@ -849,15 +859,15 @@ fn receiver_is_valid<'fcx, 'tcx, 'gcx>( let mut autoderef = fcx.autoderef(span, receiver_ty); - // the `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self` + // The `arbitrary_self_types` feature allows raw pointer receivers like `self: *const Self`. if arbitrary_self_types_enabled { autoderef = autoderef.include_raw_pointers(); } - // the first type is `receiver_ty`, which we know its not equal to `self_ty`. skip it. + // The first type is `receiver_ty`, which we know its not equal to `self_ty`; skip it. autoderef.next(); - // keep dereferencing `receiver_ty` until we get to `self_ty` + // Keep dereferencing `receiver_ty` until we get to `self_ty`. loop { if let Some((potential_self_ty, _)) = autoderef.next() { debug!("receiver_is_valid: potential self type `{:?}` to match `{:?}`", @@ -882,14 +892,14 @@ fn receiver_is_valid<'fcx, 'tcx, 'gcx>( return receiver_ty.references_error(); } - // without the `arbitrary_self_types` feature, `receiver_ty` must directly deref to - // `self_ty`. Enforce this by only doing one iteration of the loop + // Without the `arbitrary_self_types` feature, `receiver_ty` must directly deref to + // `self_ty`. Enforce this by only doing one iteration of the loop. if !arbitrary_self_types_enabled { return false } } - // without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver` + // Without `feature(arbitrary_self_types)`, we require that `receiver_ty` implements `Receiver`. if !arbitrary_self_types_enabled { let trait_def_id = match fcx.tcx.lang_items().receiver_trait() { Some(did) => did, @@ -968,7 +978,7 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut err = error_392(tcx, span, param_name); let suggested_marker_id = tcx.lang_items().phantom_data(); - // help is available only in presence of lang items + // Help is available only in presence of lang items. if let Some(def_id) = suggested_marker_id { err.help(&format!("consider removing `{}` or using a marker such as `{}`", param_name, @@ -988,12 +998,12 @@ fn reject_shadowing_parameters(tcx: TyCtxt<'_, '_, '_>, def_id: DefId) { }).collect(); for method_param in &generics.params { - // Shadowing is checked in resolve_lifetime. + // Shadowing is checked in `resolve_lifetime`. if let GenericParamDefKind::Lifetime = method_param.kind { continue } if impl_params.contains_key(&method_param.name) { - // Tighten up the span to focus on only the shadowing type + // Tighten up the span to focus on only the shadowing type. let type_span = tcx.def_span(method_param.def_id); // The expectation here is that the original trait declaration is diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f362263c16e75..ee7961197d3b0 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1488,10 +1488,13 @@ fn find_existential_constraints<'a, 'tcx>( impl<'a, 'tcx> ConstraintLocator<'a, 'tcx> { fn check(&mut self, def_id: DefId) { - trace!("checking {:?}", def_id); - // don't try to check items that cannot possibly constrain the type + // Don't try to check items that cannot possibly constrain the type. if !self.tcx.has_typeck_tables(def_id) { - trace!("no typeck tables for {:?}", def_id); + debug!( + "find_existential_constraints: no constraint for `{:?}` at `{:?}`: no tables", + self.def_id, + def_id, + ); return; } let ty = self @@ -1500,7 +1503,14 @@ fn find_existential_constraints<'a, 'tcx>( .concrete_existential_types .get(&self.def_id); if let Some(ty::ResolvedOpaqueTy { concrete_type, substs }) = ty { - // FIXME(oli-obk): trace the actual span from inference to improve errors + debug!( + "find_existential_constraints: found constraint for `{:?}` at `{:?}`: {:?}", + self.def_id, + def_id, + ty, + ); + + // FIXME(oli-obk): trace the actual span from inference to improve errors. let span = self.tcx.def_span(def_id); // used to quickly look up the position of a generic parameter let mut index_map: FxHashMap = FxHashMap::default(); @@ -1555,14 +1565,15 @@ fn find_existential_constraints<'a, 'tcx>( let mut ty = concrete_type.walk().fuse(); let mut p_ty = prev_ty.walk().fuse(); let iter_eq = (&mut ty).zip(&mut p_ty).all(|(t, p)| match (&t.sty, &p.sty) { - // type parameters are equal to any other type parameter for the purpose of + // Type parameters are equal to any other type parameter for the purpose of // concrete type equality, as it is possible to obtain the same type just // by passing matching parameters to a function. (ty::Param(_), ty::Param(_)) => true, _ => t == p, }); if !iter_eq || ty.next().is_some() || p_ty.next().is_some() { - // found different concrete types for the existential type + debug!("find_existential_constraints: span={:?}", span); + // Found different concrete types for the existential type. let mut err = self.tcx.sess.struct_span_err( span, "concrete type differs from previous defining existential type use", @@ -1574,7 +1585,7 @@ fn find_existential_constraints<'a, 'tcx>( err.span_note(prev_span, "previous use here"); err.emit(); } else if indices != *prev_indices { - // found "same" concrete types, but the generic parameter order differs + // Found "same" concrete types, but the generic parameter order differs. let mut err = self.tcx.sess.struct_span_err( span, "concrete type's generic parameters differ from previous defining use", @@ -1602,6 +1613,12 @@ fn find_existential_constraints<'a, 'tcx>( } else { self.found = Some((span, concrete_type, indices)); } + } else { + debug!( + "find_existential_constraints: no constraint for `{:?}` at `{:?}`", + self.def_id, + def_id, + ); } } } @@ -1633,26 +1650,27 @@ fn find_existential_constraints<'a, 'tcx>( } } + let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); + let scope_id = tcx.hir().get_defining_scope(hir_id) + .expect("could not get defining scope"); let mut locator = ConstraintLocator { def_id, tcx, found: None, }; - let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); - let parent = tcx.hir().get_parent_item(hir_id); - trace!("parent_id: {:?}", parent); + debug!("find_existential_constraints: scope_id={:?}", scope_id); - if parent == hir::CRATE_HIR_ID { + if scope_id == ast::CRATE_HIR_ID { intravisit::walk_crate(&mut locator, tcx.hir().krate()); } else { - trace!("parent: {:?}", tcx.hir().get_by_hir_id(parent)); - match tcx.hir().get_by_hir_id(parent) { + debug!("find_existential_constraints: scope={:?}", tcx.hir().get_by_hir_id(scope_id)); + match tcx.hir().get_by_hir_id(scope_id) { Node::Item(ref it) => intravisit::walk_item(&mut locator, it), Node::ImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it), Node::TraitItem(ref it) => intravisit::walk_trait_item(&mut locator, it), other => bug!( - "{:?} is not a valid parent of an existential type item", + "{:?} is not a valid scope for an existential type item", other ), } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 31e898048003d..598232f9f8f22 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -190,9 +190,9 @@ pub struct AngleBracketedArgs { pub span: Span, /// The arguments for this path segment. pub args: Vec, - /// Bindings (equality constraints) on associated types, if present. - /// E.g., `Foo`. - pub bindings: Vec, + /// Constraints on associated types, if any. + /// E.g., `Foo`. + pub constraints: Vec, } impl Into>> for AngleBracketedArgs { @@ -225,7 +225,7 @@ impl ParenthesizedArgs { AngleBracketedArgs { span: self.span, args: self.inputs.iter().cloned().map(|input| GenericArg::Type(input)).collect(), - bindings: vec![], + constraints: vec![], } } } @@ -1611,15 +1611,29 @@ impl fmt::Display for UintTy { } } -// Bind a type to an associated type: `A = Foo`. +/// A constraint on an associated type (e.g., `A = Bar` in `Foo` or +/// `A: TraitA + TraitB` in `Foo`). #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] -pub struct TypeBinding { +pub struct AssocTyConstraint { pub id: NodeId, pub ident: Ident, - pub ty: P, + pub kind: AssocTyConstraintKind, pub span: Span, } +/// The kinds of an `AssocTyConstraint`. +#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] +pub enum AssocTyConstraintKind { + /// E.g., `A = Bar` in `Foo`. + Equality { + ty: P, + }, + /// E.g. `A: TraitA + TraitB` in `Foo`. + Bound { + bounds: GenericBounds, + }, +} + #[derive(Clone, RustcEncodable, RustcDecodable)] pub struct Ty { pub id: NodeId, diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 435a3d7b6a22a..2a03e49996b6c 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -18,7 +18,7 @@ pub trait AstBuilder { global: bool, idents: Vec, args: Vec, - bindings: Vec) + constraints: Vec) -> ast::Path; fn qpath(&self, self_type: P, @@ -29,7 +29,7 @@ pub trait AstBuilder { trait_path: ast::Path, ident: ast::Ident, args: Vec, - bindings: Vec) + constraints: Vec) -> (ast::QSelf, ast::Path); // types and consts @@ -302,7 +302,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { global: bool, mut idents: Vec , args: Vec, - bindings: Vec ) + constraints: Vec ) -> ast::Path { assert!(!idents.is_empty()); let add_root = global && !idents[0].is_path_segment_keyword(); @@ -314,8 +314,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { segments.extend(idents.into_iter().map(|ident| { ast::PathSegment::from_ident(ident.with_span_pos(span)) })); - let args = if !args.is_empty() || !bindings.is_empty() { - ast::AngleBracketedArgs { args, bindings, span }.into() + let args = if !args.is_empty() || !constraints.is_empty() { + ast::AngleBracketedArgs { args, constraints, span }.into() } else { None }; @@ -346,11 +346,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { trait_path: ast::Path, ident: ast::Ident, args: Vec, - bindings: Vec) + constraints: Vec) -> (ast::QSelf, ast::Path) { let mut path = trait_path; - let args = if !args.is_empty() || !bindings.is_empty() { - ast::AngleBracketedArgs { args, bindings, span: ident.span }.into() + let args = if !args.is_empty() || !constraints.is_empty() { + ast::AngleBracketedArgs { args, constraints, span: ident.span }.into() } else { None }; diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 757513098995b..fb1a7a680baaf 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -163,8 +163,8 @@ pub trait MutVisitor: Sized { noop_visit_lifetime(l, self); } - fn visit_ty_binding(&mut self, t: &mut TypeBinding) { - noop_visit_ty_binding(t, self); + fn visit_ty_constraint(&mut self, t: &mut AssocTyConstraint) { + noop_visit_ty_constraint(t, self); } fn visit_mod(&mut self, m: &mut Mod) { @@ -400,11 +400,20 @@ pub fn noop_visit_guard(g: &mut Guard, vis: &mut T) { } } -pub fn noop_visit_ty_binding(TypeBinding { id, ident, ty, span }: &mut TypeBinding, - vis: &mut T) { +pub fn noop_visit_ty_constraint( + AssocTyConstraint { id, ident, kind, span }: &mut AssocTyConstraint, + vis: &mut T +) { vis.visit_id(id); vis.visit_ident(ident); - vis.visit_ty(ty); + match kind { + AssocTyConstraintKind::Equality { ref mut ty } => { + vis.visit_ty(ty); + } + AssocTyConstraintKind::Bound { ref mut bounds } => { + visit_bounds(bounds, vis); + } + } vis.visit_span(span); } @@ -499,9 +508,9 @@ pub fn noop_visit_generic_arg(arg: &mut GenericArg, vis: &mut T) pub fn noop_visit_angle_bracketed_parameter_data(data: &mut AngleBracketedArgs, vis: &mut T) { - let AngleBracketedArgs { args, bindings, span } = data; + let AngleBracketedArgs { args, constraints, span } = data; visit_vec(args, |arg| vis.visit_generic_arg(arg)); - visit_vec(bindings, |binding| vis.visit_ty_binding(binding)); + visit_vec(constraints, |constraint| vis.visit_ty_constraint(constraint)); vis.visit_span(span); } diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index abfce660c8041..790013f6eb128 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -27,7 +27,7 @@ use crate::ast::{VariantData, StructField}; use crate::ast::StrStyle; use crate::ast::SelfKind; use crate::ast::{TraitItem, TraitRef, TraitObjectSyntax}; -use crate::ast::{Ty, TyKind, TypeBinding, GenericBounds}; +use crate::ast::{Ty, TyKind, AssocTyConstraint, AssocTyConstraintKind, GenericBounds}; use crate::ast::{Visibility, VisibilityKind, WhereClause, CrateSugar}; use crate::ast::{UseTree, UseTreeKind}; use crate::ast::{BinOpKind, UnOp}; @@ -1791,11 +1791,11 @@ impl<'a> Parser<'a> { let lo = self.span; let args = if self.eat_lt() { // `<'a, T, A = U>` - let (args, bindings) = + let (args, constraints) = self.parse_generic_args_with_leaning_angle_bracket_recovery(style, lo)?; self.expect_gt()?; let span = lo.to(self.prev_span); - AngleBracketedArgs { args, bindings, span }.into() + AngleBracketedArgs { args, constraints, span }.into() } else { // `(T, U) -> R` self.bump(); // `(` @@ -5076,7 +5076,7 @@ impl<'a> Parser<'a> { &mut self, style: PathStyle, lo: Span, - ) -> PResult<'a, (Vec, Vec)> { + ) -> PResult<'a, (Vec, Vec)> { // We need to detect whether there are extra leading left angle brackets and produce an // appropriate error and suggestion. This cannot be implemented by looking ahead at // upcoming tokens for a matching `>` character - if there are unmatched `<` tokens @@ -5211,11 +5211,11 @@ impl<'a> Parser<'a> { /// Parses (possibly empty) list of lifetime and type arguments and associated type bindings, /// possibly including trailing comma. - fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec)> { + fn parse_generic_args(&mut self) -> PResult<'a, (Vec, Vec)> { let mut args = Vec::new(); - let mut bindings = Vec::new(); - let mut misplaced_assoc_ty_bindings: Vec = Vec::new(); - let mut assoc_ty_bindings: Vec = Vec::new(); + let mut constraints = Vec::new(); + let mut misplaced_assoc_ty_constraints: Vec = Vec::new(); + let mut assoc_ty_constraints: Vec = Vec::new(); let args_lo = self.span; @@ -5223,21 +5223,31 @@ impl<'a> Parser<'a> { if self.check_lifetime() && self.look_ahead(1, |t| !t.is_like_plus()) { // Parse lifetime argument. args.push(GenericArg::Lifetime(self.expect_lifetime())); - misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); - } else if self.check_ident() && self.look_ahead(1, |t| t == &token::Eq) { - // Parse associated type binding. + misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints); + } else if self.check_ident() && self.look_ahead(1, + |t| t == &token::Eq || t == &token::Colon) { + // Parse associated type constraint. let lo = self.span; let ident = self.parse_ident()?; - self.bump(); - let ty = self.parse_ty()?; + let kind = if self.eat(&token::Eq) { + AssocTyConstraintKind::Equality { + ty: self.parse_ty()?, + } + } else if self.eat(&token::Colon) { + AssocTyConstraintKind::Bound { + bounds: self.parse_generic_bounds(Some(self.prev_span))?, + } + } else { + unreachable!(); + }; let span = lo.to(self.prev_span); - bindings.push(TypeBinding { + constraints.push(AssocTyConstraint { id: ast::DUMMY_NODE_ID, ident, - ty, + kind, span, }); - assoc_ty_bindings.push(span); + assoc_ty_constraints.push(span); } else if self.check_const_arg() { // Parse const argument. let expr = if let token::OpenDelim(token::Brace) = self.token { @@ -5261,11 +5271,11 @@ impl<'a> Parser<'a> { value: expr, }; args.push(GenericArg::Const(value)); - misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); + misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints); } else if self.check_type() { // Parse type argument. args.push(GenericArg::Type(self.parse_ty()?)); - misplaced_assoc_ty_bindings.append(&mut assoc_ty_bindings); + misplaced_assoc_ty_constraints.append(&mut assoc_ty_constraints); } else { break } @@ -5278,12 +5288,12 @@ impl<'a> Parser<'a> { // FIXME: we would like to report this in ast_validation instead, but we currently do not // preserve ordering of generic parameters with respect to associated type binding, so we // lose that information after parsing. - if misplaced_assoc_ty_bindings.len() > 0 { + if misplaced_assoc_ty_constraints.len() > 0 { let mut err = self.struct_span_err( args_lo.to(self.prev_span), "associated type bindings must be declared after generic parameters", ); - for span in misplaced_assoc_ty_bindings { + for span in misplaced_assoc_ty_constraints { err.span_label( span, "this associated type binding should be moved after the generic parameters", @@ -5292,7 +5302,7 @@ impl<'a> Parser<'a> { err.emit(); } - Ok((args, bindings)) + Ok((args, constraints)) } /// Parses an optional where-clause and places it in `generics`. diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 44e1f5398d3e0..57c01e9e3efea 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -2450,14 +2450,21 @@ impl<'a> State<'a> { let mut comma = data.args.len() != 0; - for binding in data.bindings.iter() { + for constraint in data.constraints.iter() { if comma { self.word_space(",")? } - self.print_ident(binding.ident)?; + self.print_ident(constraint.ident)?; self.s.space()?; - self.word_space("=")?; - self.print_type(&binding.ty)?; + match constraint.kind { + ast::AssocTyConstraintKind::Equality { ref ty } => { + self.word_space("=")?; + self.print_type(ty)?; + } + ast::AssocTyConstraintKind::Bound { ref bounds } => { + self.print_type_bounds(":", &*bounds)?; + } + } comma = true; } diff --git a/src/libsyntax/util/node_count.rs b/src/libsyntax/util/node_count.rs index 521edac8f5fc3..f17eb3b39432e 100644 --- a/src/libsyntax/util/node_count.rs +++ b/src/libsyntax/util/node_count.rs @@ -131,9 +131,9 @@ impl<'ast> Visitor<'ast> for NodeCounter { self.count += 1; walk_generic_args(self, path_span, generic_args) } - fn visit_assoc_type_binding(&mut self, type_binding: &TypeBinding) { + fn visit_assoc_ty_constraint(&mut self, constraint: &AssocTyConstraint) { self.count += 1; - walk_assoc_type_binding(self, type_binding) + walk_assoc_ty_constraint(self, constraint) } fn visit_attribute(&mut self, _attr: &Attribute) { self.count += 1; diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index ba57055b8e009..334709b152197 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -139,8 +139,8 @@ pub trait Visitor<'ast>: Sized { GenericArg::Const(ct) => self.visit_anon_const(ct), } } - fn visit_assoc_type_binding(&mut self, type_binding: &'ast TypeBinding) { - walk_assoc_type_binding(self, type_binding) + fn visit_assoc_ty_constraint(&mut self, constraint: &'ast AssocTyConstraint) { + walk_assoc_ty_constraint(self, constraint) } fn visit_attribute(&mut self, attr: &'ast Attribute) { walk_attribute(self, attr) @@ -404,7 +404,7 @@ pub fn walk_generic_args<'a, V>(visitor: &mut V, match *generic_args { GenericArgs::AngleBracketed(ref data) => { walk_list!(visitor, visit_generic_arg, &data.args); - walk_list!(visitor, visit_assoc_type_binding, &data.bindings); + walk_list!(visitor, visit_assoc_ty_constraint, &data.constraints); } GenericArgs::Parenthesized(ref data) => { walk_list!(visitor, visit_ty, &data.inputs); @@ -413,10 +413,17 @@ pub fn walk_generic_args<'a, V>(visitor: &mut V, } } -pub fn walk_assoc_type_binding<'a, V: Visitor<'a>>(visitor: &mut V, - type_binding: &'a TypeBinding) { - visitor.visit_ident(type_binding.ident); - visitor.visit_ty(&type_binding.ty); +pub fn walk_assoc_ty_constraint<'a, V: Visitor<'a>>(visitor: &mut V, + constraint: &'a AssocTyConstraint) { + visitor.visit_ident(constraint.ident); + match constraint.kind { + AssocTyConstraintKind::Equality { ref ty } => { + visitor.visit_ty(ty); + } + AssocTyConstraintKind::Bound { ref bounds } => { + walk_list!(visitor, visit_param_bound, bounds); + } + } } pub fn walk_pat<'a, V: Visitor<'a>>(visitor: &mut V, pattern: &'a Pat) { From aaa53ec8531565e2f5721548b5a38c0062aa0e51 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 16 Mar 2019 00:04:02 +0000 Subject: [PATCH 04/24] Implemented for traits (associated type definitions). --- src/librustc/hir/intravisit.rs | 3 + src/librustc/hir/lowering.rs | 54 +++-- src/librustc/hir/mod.rs | 2 + src/librustc/hir/print.rs | 3 + src/librustc/infer/opaque_types/mod.rs | 12 +- src/librustc_interface/util.rs | 3 +- src/librustc_privacy/lib.rs | 5 +- src/librustc_typeck/astconv.rs | 289 +++++++++++++++++++------ src/librustc_typeck/check/regionck.rs | 4 +- src/librustc_typeck/collect.rs | 172 +++------------ src/librustc_typeck/lib.rs | 11 +- src/librustdoc/clean/mod.rs | 5 +- 12 files changed, 313 insertions(+), 250 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index f838ec84d8b31..da4d41c9d872f 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -626,6 +626,9 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { TyKind::CVarArgs(ref lt) => { visitor.visit_lifetime(lt) } + TyKind::AssocTyExistential(ref bounds) => { + walk_list!(visitor, visit_param_bound, bounds); + } TyKind::Infer | TyKind::Err => {} } } diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 5a0e9d53b0833..2c2cd6a2f6f53 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -195,6 +195,12 @@ enum ImplTraitContext<'a> { /// (e.g., for consts and statics). Existential(Option /* fn def-ID */), + /// Treat `impl Trait` as a bound on the associated type applied to the trait. + /// Example: `trait Foo { type Bar: Iterator; }` is conceptually + /// equivalent to `trait Foo where ::Item: Debug + /// { type Bar: Iterator; }`. + AssociatedTy, + /// `impl Trait` is not accepted in this position. Disallowed(ImplTraitPosition), } @@ -217,6 +223,7 @@ impl<'a> ImplTraitContext<'a> { match self { Universal(params) => Universal(params), Existential(fn_def_id) => Existential(*fn_def_id), + AssociatedTy => AssociatedTy, Disallowed(pos) => Disallowed(*pos), } } @@ -1537,6 +1544,16 @@ impl<'a> LoweringContext<'a> { }), )) } + ImplTraitContext::AssociatedTy => { + let hir_bounds = self.lower_param_bounds( + bounds, + ImplTraitContext::AssociatedTy, + ); + + hir::TyKind::AssocTyExistential( + hir_bounds, + ) + } ImplTraitContext::Disallowed(pos) => { let allowed_in = if self.sess.features_untracked() .impl_trait_in_bindings { @@ -1640,8 +1657,8 @@ impl<'a> LoweringContext<'a> { }) } - /// Registers a new existential type with the proper `NodeId`ss and - /// returns the lowered node ID for the existential type. + /// Registers a new existential type with the proper `NodeId`s and + /// returns the lowered node-ID for the existential type. fn generate_existential_type( &mut self, exist_ty_node_id: NodeId, @@ -2226,8 +2243,9 @@ impl<'a> LoweringContext<'a> { ( hir::GenericArgs { args: args.iter().map(|a| self.lower_generic_arg(a, itctx.reborrow())).collect(), - bindings: constraints.iter().map( - |b| self.lower_assoc_ty_constraint(b, itctx.reborrow())).collect(), + bindings: constraints.iter() + .map(|b| self.lower_assoc_ty_constraint(b, itctx.reborrow())) + .collect(), parenthesized: false, }, !has_types && param_mode == ParamMode::Optional @@ -3257,13 +3275,13 @@ impl<'a> LoweringContext<'a> { ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)), ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)), ItemKind::Ty(ref t, ref generics) => hir::ItemKind::Ty( - self.lower_ty(t, ImplTraitContext::disallowed()), - self.lower_generics(generics, ImplTraitContext::disallowed()), + self.lower_ty(t, ImplTraitContext::AssociatedTy), + self.lower_generics(generics, ImplTraitContext::AssociatedTy), ), ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential( hir::ExistTy { - generics: self.lower_generics(generics, ImplTraitContext::disallowed()), - bounds: self.lower_param_bounds(b, ImplTraitContext::Existential(None)), + generics: self.lower_generics(generics, ImplTraitContext::AssociatedTy), + bounds: self.lower_param_bounds(b, ImplTraitContext::AssociatedTy), impl_trait_fn: None, origin: hir::ExistTyOrigin::ExistentialType, }, @@ -3276,20 +3294,20 @@ impl<'a> LoweringContext<'a> { .map(|x| self.lower_variant(x)) .collect(), }, - self.lower_generics(generics, ImplTraitContext::disallowed()), + self.lower_generics(generics, ImplTraitContext::AssociatedTy), ), ItemKind::Struct(ref struct_def, ref generics) => { let struct_def = self.lower_variant_data(struct_def); hir::ItemKind::Struct( struct_def, - self.lower_generics(generics, ImplTraitContext::disallowed()), + self.lower_generics(generics, ImplTraitContext::AssociatedTy), ) } ItemKind::Union(ref vdata, ref generics) => { let vdata = self.lower_variant_data(vdata); hir::ItemKind::Union( vdata, - self.lower_generics(generics, ImplTraitContext::disallowed()), + self.lower_generics(generics, ImplTraitContext::AssociatedTy), ) } ItemKind::Impl( @@ -3656,15 +3674,17 @@ impl<'a> LoweringContext<'a> { ); (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id))) } - TraitItemKind::Type(ref bounds, ref default) => ( - self.lower_generics(&i.generics, ImplTraitContext::disallowed()), - hir::TraitItemKind::Type( - self.lower_param_bounds(bounds, ImplTraitContext::disallowed()), + TraitItemKind::Type(ref bounds, ref default) => { + let generics = self.lower_generics(&i.generics, ImplTraitContext::AssociatedTy); + let node = hir::TraitItemKind::Type( + self.lower_param_bounds(bounds, ImplTraitContext::AssociatedTy), default .as_ref() .map(|x| self.lower_ty(x, ImplTraitContext::disallowed())), - ), - ), + ); + + (generics, node) + }, TraitItemKind::Macro(..) => bug!("macro item shouldn't exist at this point"), }; diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index e29998db7778f..20968ec6a63be 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1898,6 +1898,8 @@ pub enum TyKind { /// Placeholder for C-variadic arguments. We "spoof" the `VaList` created /// from the variadic arguments. This type is only valid up to typeck. CVarArgs(Lifetime), + /// The existential type (i.e., `impl Trait`) that constrains an associated type. + AssocTyExistential(HirVec), } #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 709a43c4734c1..c8f9e4c7043e0 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -409,6 +409,9 @@ impl<'a> State<'a> { hir::TyKind::CVarArgs(_) => { self.s.word("...")?; } + hir::TyKind::AssocTyExistential(ref bounds) => { + self.print_bounds(":", bounds)?; + } } self.end() } diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index ef216110c9e62..2127fbbd56e93 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -948,15 +948,17 @@ pub fn may_define_existential_type( let mut hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); trace!( "may_define_existential_type(def={:?}, opaque_node={:?})", - tcx.hir().get(hir_id), - tcx.hir().get(opaque_hir_id) + tcx.hir().get_by_hir_id(hir_id), + tcx.hir().get_by_hir_id(opaque_hir_id) ); // Named existential types can be defined by any siblings or children of siblings. - let scope_id = tcx.hir().get_defining_scope(opaque_hir_id) - .expect("could not get defining scope"); + let scope_node_id = tcx.hir() + .get_defining_scope(tcx.hir().hir_to_node_id(opaque_hir_id)) + .expect("could not get defining scope"); + let scope_id = tcx.hir().node_to_hir_id(scope_node_id); // We walk up the node tree until we hit the root or the scope of the opaque type. - while hir_id != scope_id && hir_id != ast::CRATE_hir_ID { + while hir_id != scope_id && hir_id != hir::CRATE_HIR_ID { hir_id = tcx.hir().get_parent_item(hir_id); } // Syntactically, we are allowed to define the concrete type if: diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index f49f2110f2365..fe24eab9f4439 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -726,7 +726,8 @@ impl<'a> ReplaceBodyWithLoop<'a> { any_assoc_ty_bounds || any_involves_impl_trait(types.into_iter()) || any_involves_impl_trait(data.constraints.iter().filter_map(|c| { - if let ast::AssocTyConstraintKind::Equality { ref ty } = c.kind { + if let ast::AssocTyConstraintKind::Equality { ref ty } + = c.kind { Some(ty) } else { None diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index f084d3b9f28c3..6d01328cd16e6 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -1040,12 +1040,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> { if !self.in_body { // Avoid calling `hir_trait_to_predicates` in bodies, it will ICE. // The traits' privacy in bodies is already checked as a part of trait object types. - let (principal, projections) = - rustc_typeck::hir_trait_to_predicates(self.tcx, trait_ref); + let (principal, bounds) = rustc_typeck::hir_trait_to_predicates(self.tcx, trait_ref); if self.visit_trait(*principal.skip_binder()) { return; } - for (poly_predicate, _) in projections { + for (poly_predicate, _) in bounds.projection_bounds { let tcx = self.tcx; if self.visit(poly_predicate.skip_binder().ty) || self.visit_trait(poly_predicate.skip_binder().projection_ty.trait_ref(tcx)) { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f6e3f1a99e831..6123ee2af6e88 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -8,6 +8,7 @@ use crate::hir::def::{CtorOf, Res, DefKind}; use crate::hir::def_id::DefId; use crate::hir::HirVec; use crate::lint; +use crate::middle::lang_items::SizedTraitLangItem; use crate::middle::resolve_lifetime as rl; use crate::namespace::Namespace; use rustc::lint::builtin::AMBIGUOUS_ASSOCIATED_ITEMS; @@ -86,12 +87,22 @@ pub trait AstConv<'gcx, 'tcx> { fn record_ty(&self, hir_id: hir::HirId, ty: Ty<'tcx>, span: Span); } +pub enum SizedByDefault { + Yes, + No, +} + struct ConvertedBinding<'tcx> { item_name: ast::Ident, - ty: Ty<'tcx>, + kind: ConvertedBindingKind<'tcx>, span: Span, } +enum ConvertedBindingKind<'tcx> { + Equality(Ty<'tcx>), + Constraint(P<[hir::GenericBound]>), +} + #[derive(PartialEq)] enum GenericArgPosition { Type, @@ -562,10 +573,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { /// set of substitutions. This may involve applying defaulted type parameters. /// /// Note that the type listing given here is *exactly* what the user provided. - fn create_substs_for_ast_path(&self, + fn create_substs_for_ast_path<'a>(&self, span: Span, def_id: DefId, - generic_args: &hir::GenericArgs, + generic_args: &'a hir::GenericArgs, infer_types: bool, self_ty: Option>) -> (SubstsRef<'tcx>, Vec>, Option>) @@ -688,13 +699,20 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }, ); - let assoc_bindings = generic_args.bindings.iter().map(|binding| { - ConvertedBinding { - item_name: binding.ident, - ty: self.ast_ty_to_ty(&binding.ty), - span: binding.span, - } - }).collect(); + let assoc_bindings = generic_args.bindings.iter() + .map(|binding| { + let kind = if let hir::TyKind::AssocTyExistential(ref bounds) = binding.ty.node { + ConvertedBindingKind::Constraint(bounds.clone()) + } else { + ConvertedBindingKind::Equality(self.ast_ty_to_ty(&binding.ty)) + }; + ConvertedBinding { + item_name: binding.ident, + kind, + span: binding.span, + } + }) + .collect(); debug!("create_substs_for_ast_path(generic_params={:?}, self_ty={:?}) -> {:?}", generic_params, self_ty, substs); @@ -725,7 +743,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { pub(super) fn instantiate_poly_trait_ref_inner(&self, trait_ref: &hir::TraitRef, self_ty: Ty<'tcx>, - poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, + bounds: &mut Bounds<'tcx>, speculative: bool, ) -> (ty::PolyTraitRef<'tcx>, Option>) { @@ -744,36 +762,40 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let poly_trait_ref = ty::Binder::bind(ty::TraitRef::new(trait_def_id, substs)); let mut dup_bindings = FxHashMap::default(); - poly_projections.extend(assoc_bindings.iter().filter_map(|binding| { - // specify type to assert that error was already reported in Err case: - let predicate: Result<_, ErrorReported> = - self.ast_type_binding_to_poly_projection_predicate( - trait_ref.hir_ref_id, poly_trait_ref, binding, speculative, &mut dup_bindings); - // okay to ignore Err because of ErrorReported (see above) - Some((predicate.ok()?, binding.span)) - })); - - debug!("instantiate_poly_trait_ref({:?}, projections={:?}) -> {:?}", - trait_ref, poly_projections, poly_trait_ref); + for binding in &assoc_bindings { + // Specify type to assert that error was already reported in `Err` case. + let _ = + self.add_predicates_for_ast_type_binding( + trait_ref.hir_ref_id, + poly_trait_ref, + binding, + bounds, + speculative, + &mut dup_bindings + ); + // Okay to ignore `Err` because of `ErrorReported` (see above). + } + + debug!("instantiate_poly_trait_ref({:?}, bounds={:?}) -> {:?}", + trait_ref, bounds, poly_trait_ref); (poly_trait_ref, potential_assoc_types) } pub fn instantiate_poly_trait_ref(&self, poly_trait_ref: &hir::PolyTraitRef, self_ty: Ty<'tcx>, - poly_projections: &mut Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>) - -> (ty::PolyTraitRef<'tcx>, Option>) + bounds: &mut Bounds<'tcx> + ) -> (ty::PolyTraitRef<'tcx>, Option>) { - self.instantiate_poly_trait_ref_inner(&poly_trait_ref.trait_ref, self_ty, - poly_projections, false) + self.instantiate_poly_trait_ref_inner(&poly_trait_ref.trait_ref, self_ty, bounds, false) } fn ast_path_to_mono_trait_ref(&self, - span: Span, - trait_def_id: DefId, - self_ty: Ty<'tcx>, - trait_segment: &hir::PathSegment) - -> ty::TraitRef<'tcx> + span: Span, + trait_def_id: DefId, + self_ty: Ty<'tcx>, + trait_segment: &hir::PathSegment + ) -> ty::TraitRef<'tcx> { let (substs, assoc_bindings, _) = self.create_substs_for_ast_trait_ref(span, @@ -830,15 +852,120 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }) } - fn ast_type_binding_to_poly_projection_predicate( + // Returns `true` if a bounds list includes `?Sized`. + pub fn is_unsized(&self, ast_bounds: &[hir::GenericBound], span: Span) -> bool { + let tcx = self.tcx(); + + // Try to find an unbound in bounds. + let mut unbound = None; + for ab in ast_bounds { + if let &hir::GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = ab { + if unbound.is_none() { + unbound = Some(ptr.trait_ref.clone()); + } else { + span_err!( + tcx.sess, + span, + E0203, + "type parameter has more than one relaxed default \ + bound, only one is supported" + ); + } + } + } + + let kind_id = tcx.lang_items().require(SizedTraitLangItem); + match unbound { + Some(ref tpb) => { + // FIXME(#8559) currently requires the unbound to be built-in. + if let Ok(kind_id) = kind_id { + if tpb.path.res != Res::Def(DefKind::Trait, kind_id) { + tcx.sess.span_warn( + span, + "default bound relaxed for a type parameter, but \ + this does nothing because the given bound is not \ + a default. Only `?Sized` is supported", + ); + } + } + } + _ if kind_id.is_ok() => { + return false; + } + // No lang item for `Sized`, so we can't add it as a bound. + None => {} + } + + true + } + + pub fn add_bounds(&self, + param_ty: Ty<'tcx>, + ast_bounds: &[hir::GenericBound], + bounds: &mut Bounds<'tcx>, + ) { + let mut trait_bounds = Vec::new(); + let mut region_bounds = Vec::new(); + + for ast_bound in ast_bounds { + match *ast_bound { + hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => + trait_bounds.push(b), + hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {} + hir::GenericBound::Outlives(ref l) => + region_bounds.push(l), + } + } + + for bound in trait_bounds { + let (poly_trait_ref, _) = self.instantiate_poly_trait_ref( + bound, + param_ty, + bounds, + ); + bounds.trait_bounds.push((poly_trait_ref, bound.span)) + } + + bounds.region_bounds.extend(region_bounds + .into_iter() + .map(|r| (self.ast_region_to_region(r, None), r.span)) + ); + + bounds.trait_bounds.sort_by_key(|(t, _)| t.def_id()); + } + + /// Translates the AST's notion of ty param bounds (which are an enum consisting of a newtyped `Ty` + /// or a region) to ty's notion of ty param bounds, which can either be user-defined traits or the + /// built-in trait `Send`. + pub fn compute_bounds(&self, + param_ty: Ty<'tcx>, + ast_bounds: &[hir::GenericBound], + sized_by_default: SizedByDefault, + span: Span, + ) -> Bounds<'tcx> { + let mut bounds = Bounds::default(); + self.add_bounds(param_ty, ast_bounds, &mut bounds); + bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default { + if !self.is_unsized(ast_bounds, span) { + Some(span) + } else { + None + } + } else { + None + }; + bounds + } + + fn add_predicates_for_ast_type_binding( &self, hir_ref_id: hir::HirId, trait_ref: ty::PolyTraitRef<'tcx>, binding: &ConvertedBinding<'tcx>, + bounds: &mut Bounds<'tcx>, speculative: bool, - dup_bindings: &mut FxHashMap) - -> Result, ErrorReported> - { + dup_bindings: &mut FxHashMap, + ) -> Result<(), ErrorReported> { let tcx = self.tcx(); if !speculative { @@ -865,28 +992,30 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // // for<'a> ::Item = &'a str // <-- 'a is bad // for<'a> >::Output = &'a str // <-- 'a is ok - let late_bound_in_trait_ref = tcx.collect_constrained_late_bound_regions(&trait_ref); - let late_bound_in_ty = - tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(binding.ty)); - debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref); - debug!("late_bound_in_ty = {:?}", late_bound_in_ty); - for br in late_bound_in_ty.difference(&late_bound_in_trait_ref) { - let br_name = match *br { - ty::BrNamed(_, name) => name, - _ => { - span_bug!( - binding.span, - "anonymous bound region {:?} in binding but not trait ref", - br); - } - }; - struct_span_err!(tcx.sess, + if let ConvertedBindingKind::Equality(ty) = binding.kind { + let late_bound_in_trait_ref = tcx.collect_constrained_late_bound_regions(&trait_ref); + let late_bound_in_ty = + tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty)); + debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref); + debug!("late_bound_in_ty = {:?}", late_bound_in_ty); + for br in late_bound_in_ty.difference(&late_bound_in_trait_ref) { + let br_name = match *br { + ty::BrNamed(_, name) => name, + _ => { + span_bug!( binding.span, - E0582, - "binding for associated type `{}` references lifetime `{}`, \ - which does not appear in the trait input types", - binding.item_name, br_name) - .emit(); + "anonymous bound region {:?} in binding but not trait ref", + br); + } + }; + struct_span_err!(tcx.sess, + binding.span, + E0582, + "binding for associated type `{}` references lifetime `{}`, \ + which does not appear in the trait input types", + binding.item_name, br_name) + .emit(); + } } } @@ -931,16 +1060,28 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { .or_insert(binding.span); } - Ok(candidate.map_bound(|trait_ref| { - ty::ProjectionPredicate { - projection_ty: ty::ProjectionTy::from_ref_and_name( - tcx, - trait_ref, - binding.item_name, - ), - ty: binding.ty, + match binding.kind { + ConvertedBindingKind::Equality(ref ty) => { + bounds.projection_bounds.push((candidate.map_bound(|trait_ref| { + ty::ProjectionPredicate { + projection_ty: ty::ProjectionTy::from_ref_and_name( + tcx, + trait_ref, + binding.item_name, + ), + ty, + } + }), binding.span)); } - })) + ConvertedBindingKind::Constraint(ref ast_bounds) => { + self.add_bounds( + trait_ref.self_ty(), + ast_bounds, + bounds, + ); + } + } + Ok(()) } fn ast_path_to_ty(&self, @@ -974,7 +1115,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { { let tcx = self.tcx(); - let mut projection_bounds = Vec::new(); + let mut bounds = Bounds::default(); let mut potential_assoc_types = Vec::new(); let dummy_self = self.tcx().types.trait_object_dummy_self; // FIXME: we want to avoid collecting into a `Vec` here, but simply cloning the iterator is @@ -986,7 +1127,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let (trait_ref, cur_potential_assoc_types) = self.instantiate_poly_trait_ref( trait_bound, dummy_self, - &mut projection_bounds + &mut bounds, ); potential_assoc_types.extend(cur_potential_assoc_types.into_iter().flatten()); (trait_ref, trait_bound.span) @@ -1074,14 +1215,14 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // which is uglier but works. See the discussion in #56288 for alternatives. if !references_self { // Include projections defined on supertraits. - projection_bounds.push((pred, DUMMY_SP)) + bounds.projection_bounds.push((pred, DUMMY_SP)) } } _ => () } } - for (projection_bound, _) in &projection_bounds { + for (projection_bound, _) in &bounds.projection_bounds { associated_types.remove(&projection_bound.projection_def_id()); } @@ -1161,7 +1302,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let existential_trait_refs = regular_traits.iter().map(|i| { i.trait_ref().map_bound(|trait_ref| self.trait_ref_to_existential(trait_ref)) }); - let existential_projections = projection_bounds.iter().map(|(bound, _)| { + let existential_projections = bounds.projection_bounds.iter().map(|(bound, _)| { bound.map_bound(|b| { let trait_ref = self.trait_ref_to_existential(b.projection_ty.trait_ref(tcx)); ty::ExistentialProjection { @@ -1900,6 +2041,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let region = self.ast_region_to_region(<, None); tcx.type_of(va_list_did).subst(tcx, &[region.into()]) } + hir::TyKind::AssocTyExistential(..) => { + // Type is never actually used. + tcx.types.err + } hir::TyKind::Err => { tcx.types.err } @@ -2121,12 +2266,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // A helper struct for conveniently grouping a set of bounds which we pass to // and return from functions in multiple places. -#[derive(PartialEq, Eq, Clone, Debug)] +#[derive(Default, PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { pub region_bounds: Vec<(ty::Region<'tcx>, Span)>, - pub implicitly_sized: Option, pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span)>, pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, + pub implicitly_sized: Option, } impl<'a, 'gcx, 'tcx> Bounds<'tcx> { diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 21d7e483e9d15..c3b6fb21e38d6 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -991,8 +991,8 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { } } - /// Guarantees that any lifetimes which appear in the type of the node `id` (after applying - /// adjustments) are valid for at least `minimum_lifetime` + /// Guarantees that any lifetimes that appear in the type of the node `id` (after applying + /// adjustments) are valid for at least `minimum_lifetime`. fn type_of_node_must_outlive( &mut self, origin: infer::SubregionOrigin<'tcx>, diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index ee7961197d3b0..92d0e37cb9bbd 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -14,11 +14,10 @@ //! At present, however, we do run collection across all items in the //! crate as a kind of pass. This should eventually be factored away. -use crate::astconv::{AstConv, Bounds}; +use crate::astconv::{AstConv, Bounds, SizedByDefault}; use crate::constrained_generic_params as cgp; use crate::check::intrinsic::intrisic_operation_unsafety; use crate::lint; -use crate::middle::lang_items::SizedTraitLangItem; use crate::middle::resolve_lifetime as rl; use crate::middle::weak_lang_items; use rustc::mir::mono::Linkage; @@ -704,7 +703,7 @@ fn super_predicates_of<'a, 'tcx>( // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`. let self_param_ty = tcx.mk_self_type(); - let superbounds1 = compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span); + let superbounds1 = AstConv::compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span); let superbounds1 = superbounds1.predicates(tcx, self_param_ty); @@ -1650,9 +1649,11 @@ fn find_existential_constraints<'a, 'tcx>( } } - let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); - let scope_id = tcx.hir().get_defining_scope(hir_id) - .expect("could not get defining scope"); + let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); + let scope_node_id = tcx.hir() + .get_defining_scope(node_id) + .expect("could not get defining scope"); + let scope_id = tcx.hir().node_to_hir_id(scope_node_id); let mut locator = ConstraintLocator { def_id, tcx, @@ -1661,7 +1662,7 @@ fn find_existential_constraints<'a, 'tcx>( debug!("find_existential_constraints: scope_id={:?}", scope_id); - if scope_id == ast::CRATE_HIR_ID { + if scope_id == hir::CRATE_HIR_ID { intravisit::walk_crate(&mut locator, tcx.hir().krate()); } else { debug!("find_existential_constraints: scope={:?}", tcx.hir().get_by_hir_id(scope_id)); @@ -1788,57 +1789,6 @@ fn impl_polarity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> hir::I } } -// Is it marked with ?Sized -fn is_unsized<'gcx: 'tcx, 'tcx>( - astconv: &dyn AstConv<'gcx, 'tcx>, - ast_bounds: &[hir::GenericBound], - span: Span, -) -> bool { - let tcx = astconv.tcx(); - - // Try to find an unbound in bounds. - let mut unbound = None; - for ab in ast_bounds { - if let &hir::GenericBound::Trait(ref ptr, hir::TraitBoundModifier::Maybe) = ab { - if unbound.is_none() { - unbound = Some(ptr.trait_ref.clone()); - } else { - span_err!( - tcx.sess, - span, - E0203, - "type parameter has more than one relaxed default \ - bound, only one is supported" - ); - } - } - } - - let kind_id = tcx.lang_items().require(SizedTraitLangItem); - match unbound { - Some(ref tpb) => { - // FIXME(#8559) currently requires the unbound to be built-in. - if let Ok(kind_id) = kind_id { - if tpb.path.res != Res::Def(DefKind::Trait, kind_id) { - tcx.sess.span_warn( - span, - "default bound relaxed for a type parameter, but \ - this does nothing because the given bound is not \ - a default. Only `?Sized` is supported", - ); - } - } - } - _ if kind_id.is_ok() => { - return false; - } - // No lang item for Sized, so we can't add it as a bound. - None => {} - } - - true -} - /// Returns the early-bound lifetimes declared in this generics /// listing. For anything other than fns/methods, this is just all /// the lifetimes that are declared. For fns or methods, we have to @@ -1984,7 +1934,7 @@ fn explicit_predicates_of<'a, 'tcx>( let opaque_ty = tcx.mk_opaque(def_id, substs); // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`. - let bounds = compute_bounds( + let bounds = AstConv::compute_bounds( &icx, opaque_ty, bounds, @@ -2030,7 +1980,7 @@ fn explicit_predicates_of<'a, 'tcx>( let opaque_ty = tcx.mk_opaque(def_id, substs); // Collect the bounds, i.e., the `A + B + 'c` in `impl A + B + 'c`. - let bounds = compute_bounds( + let bounds = AstConv::compute_bounds( &icx, opaque_ty, bounds, @@ -2124,7 +2074,7 @@ fn explicit_predicates_of<'a, 'tcx>( index += 1; let sized = SizedByDefault::Yes; - let bounds = compute_bounds(&icx, param_ty, ¶m.bounds, sized, param.span); + let bounds = AstConv::compute_bounds(&icx, param_ty, ¶m.bounds, sized, param.span); predicates.extend(bounds.predicates(tcx, param_ty)); } } @@ -2159,19 +2109,17 @@ fn explicit_predicates_of<'a, 'tcx>( for bound in bound_pred.bounds.iter() { match bound { &hir::GenericBound::Trait(ref poly_trait_ref, _) => { - let mut projections = Vec::new(); + let mut bounds = Bounds::default(); let (trait_ref, _) = AstConv::instantiate_poly_trait_ref( &icx, poly_trait_ref, ty, - &mut projections, + &mut bounds, ); - predicates.extend( - iter::once((trait_ref.to_predicate(), poly_trait_ref.span)).chain( - projections.iter().map(|&(p, span)| (p.to_predicate(), span) - ))); + predicates.push((trait_ref.to_predicate(), poly_trait_ref.span)); + predicates.extend(bounds.predicates(tcx, ty)); } &hir::GenericBound::Outlives(ref lifetime) => { @@ -2210,14 +2158,14 @@ fn explicit_predicates_of<'a, 'tcx>( let trait_item = tcx.hir().trait_item(trait_item_ref.id); let bounds = match trait_item.node { hir::TraitItemKind::Type(ref bounds, _) => bounds, - _ => return vec![].into_iter() + _ => return Vec::new().into_iter() }; let assoc_ty = tcx.mk_projection(tcx.hir().local_def_id_from_hir_id(trait_item.hir_id), self_trait_ref.substs); - let bounds = compute_bounds( + let bounds = AstConv::compute_bounds( &ItemCtxt::new(tcx, def_id), assoc_ty, bounds, @@ -2259,68 +2207,6 @@ fn explicit_predicates_of<'a, 'tcx>( result } -pub enum SizedByDefault { - Yes, - No, -} - -/// Translate the AST's notion of ty param bounds (which are an enum consisting of a newtyped `Ty` -/// or a region) to ty's notion of ty param bounds, which can either be user-defined traits, or the -/// built-in trait `Send`. -pub fn compute_bounds<'gcx: 'tcx, 'tcx>( - astconv: &dyn AstConv<'gcx, 'tcx>, - param_ty: Ty<'tcx>, - ast_bounds: &[hir::GenericBound], - sized_by_default: SizedByDefault, - span: Span, -) -> Bounds<'tcx> { - let mut region_bounds = Vec::new(); - let mut trait_bounds = Vec::new(); - - for ast_bound in ast_bounds { - match *ast_bound { - hir::GenericBound::Trait(ref b, hir::TraitBoundModifier::None) => trait_bounds.push(b), - hir::GenericBound::Trait(_, hir::TraitBoundModifier::Maybe) => {} - hir::GenericBound::Outlives(ref l) => region_bounds.push(l), - } - } - - let mut projection_bounds = Vec::new(); - - let mut trait_bounds: Vec<_> = trait_bounds.iter().map(|&bound| { - let (poly_trait_ref, _) = astconv.instantiate_poly_trait_ref( - bound, - param_ty, - &mut projection_bounds, - ); - (poly_trait_ref, bound.span) - }).collect(); - - let region_bounds = region_bounds - .into_iter() - .map(|r| (astconv.ast_region_to_region(r, None), r.span)) - .collect(); - - trait_bounds.sort_by_key(|(t, _)| t.def_id()); - - let implicitly_sized = if let SizedByDefault::Yes = sized_by_default { - if !is_unsized(astconv, ast_bounds, span) { - Some(span) - } else { - None - } - } else { - None - }; - - Bounds { - region_bounds, - implicitly_sized, - trait_bounds, - projection_bounds, - } -} - /// Converts a specific `GenericBound` from the AST into a set of /// predicates that apply to the self type. A vector is returned /// because this can be anywhere from zero predicates (`T: ?Sized` adds no @@ -2333,13 +2219,11 @@ fn predicates_from_bound<'tcx>( ) -> Vec<(ty::Predicate<'tcx>, Span)> { match *bound { hir::GenericBound::Trait(ref tr, hir::TraitBoundModifier::None) => { - let mut projections = Vec::new(); - let (pred, _) = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut projections); - iter::once((pred.to_predicate(), tr.span)).chain( - projections - .into_iter() - .map(|(p, span)| (p.to_predicate(), span)) - ).collect() + let mut bounds = Bounds::default(); + let (pred, _) = astconv.instantiate_poly_trait_ref(tr, param_ty, &mut bounds); + iter::once((pred.to_predicate(), tr.span)) + .chain(bounds.predicates(astconv.tcx(), param_ty)) + .collect() } hir::GenericBound::Outlives(ref lifetime) => { let region = astconv.ast_region_to_region(lifetime, None); @@ -2363,8 +2247,8 @@ fn compute_sig_of_foreign_fn_decl<'a, 'tcx>( }; let fty = AstConv::ty_of_fn(&ItemCtxt::new(tcx, def_id), unsafety, abi, decl); - // feature gate SIMD types in FFI, since I (huonw) am not sure the - // ABIs are handled at all correctly. + // Feature gate SIMD types in FFI, since I am not sure that the + // ABIs are handled at all correctly. -huonw if abi != abi::Abi::RustIntrinsic && abi != abi::Abi::PlatformIntrinsic && !tcx.features().simd_ffi @@ -2439,7 +2323,7 @@ fn from_target_feature( }; let rust_features = tcx.features(); for item in list { - // Only `enable = ...` is accepted in the meta item list + // Only `enable = ...` is accepted in the meta-item list. if !item.check_name(sym::enable) { bad_item(item.span()); continue; @@ -2454,9 +2338,9 @@ fn from_target_feature( } }; - // We allow comma separation to enable multiple features + // We allow comma separation to enable multiple features. target_features.extend(value.as_str().split(',').filter_map(|feature| { - // Only allow whitelisted features per platform + // Only allow whitelisted features per platform. let feature_gate = match whitelist.get(feature) { Some(g) => g, None => { @@ -2480,7 +2364,7 @@ fn from_target_feature( } }; - // Only allow features whose feature gates have been enabled + // Only allow features whose feature gates have been enabled. let allowed = match feature_gate.as_ref().map(|s| *s) { Some(sym::arm_target_feature) => rust_features.arm_target_feature, Some(sym::aarch64_target_feature) => rust_features.aarch64_target_feature, diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 024d73ff65bd2..30993b86a385f 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -114,6 +114,7 @@ use util::common::time; use std::iter; +use astconv::{AstConv, Bounds}; pub use collect::checked_type_of; pub struct TypeAndSubsts<'tcx> { @@ -390,19 +391,19 @@ pub fn hir_ty_to_ty<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_ty: &hir::Ty) -> } pub fn hir_trait_to_predicates<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, hir_trait: &hir::TraitRef) - -> (ty::PolyTraitRef<'tcx>, Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>) { + -> (ty::PolyTraitRef<'tcx>, Bounds<'tcx>) { // In case there are any projections, etc., find the "environment" // def-ID that will be used to determine the traits/predicates in // scope. This is derived from the enclosing item-like thing. let env_hir_id = tcx.hir().get_parent_item(hir_trait.hir_ref_id); let env_def_id = tcx.hir().local_def_id_from_hir_id(env_hir_id); let item_cx = self::collect::ItemCtxt::new(tcx, env_def_id); - let mut projections = Vec::new(); - let (principal, _) = astconv::AstConv::instantiate_poly_trait_ref_inner( - &item_cx, hir_trait, tcx.types.err, &mut projections, true + let mut bounds = Bounds::default(); + let (principal, _) = AstConv::instantiate_poly_trait_ref_inner( + &item_cx, hir_trait, tcx.types.err, &mut bounds, true ); - (principal, projections) + (principal, bounds) } __build_diagnostic_array! { librustc_typeck, DIAGNOSTICS } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f19e5180939ba..161e426604e94 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2445,7 +2445,7 @@ pub struct PolyTrait { /// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original /// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most -/// importantly, it does not preserve mutability or boxes. +/// importanntly, it does not preserve mutability or boxes. #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] pub enum Type { /// Structs/enums/traits (most that would be an `hir::TyKind::Path`). @@ -2939,6 +2939,9 @@ impl Clean for hir::Ty { TyKind::Infer | TyKind::Err => Infer, TyKind::Typeof(..) => panic!("Unimplemented type {:?}", self.node), TyKind::CVarArgs(_) => CVarArgs, + TyKind::AssocTyExistential(ref bounds) => { + ImplTrait(bounds.into_iter().map(|b| b.clean(cx)).collect()) + } } } } From 01f49f0bb2461ebe1987a40c6afea5b1dd30e881 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 21 Mar 2019 17:55:09 +0000 Subject: [PATCH 05/24] Use both existential-type desugaring and where-clause (predicate) desugaring depending on context. --- src/librustc/hir/lowering.rs | 182 ++++++++++++++++---------- src/librustc_passes/ast_validation.rs | 46 ++++++- src/librustc_typeck/astconv.rs | 24 ++-- src/librustc_typeck/collect.rs | 8 +- 4 files changed, 173 insertions(+), 87 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 2c2cd6a2f6f53..165723bcfa278 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -106,6 +106,7 @@ pub struct LoweringContext<'a> { loop_scopes: Vec, is_in_loop_condition: bool, is_in_trait_impl: bool, + is_in_dyn_type: bool, /// What to do when we encounter either an "anonymous lifetime /// reference". The term "anonymous" is meant to encompass both @@ -195,12 +196,6 @@ enum ImplTraitContext<'a> { /// (e.g., for consts and statics). Existential(Option /* fn def-ID */), - /// Treat `impl Trait` as a bound on the associated type applied to the trait. - /// Example: `trait Foo { type Bar: Iterator; }` is conceptually - /// equivalent to `trait Foo where ::Item: Debug - /// { type Bar: Iterator; }`. - AssociatedTy, - /// `impl Trait` is not accepted in this position. Disallowed(ImplTraitPosition), } @@ -208,7 +203,10 @@ enum ImplTraitContext<'a> { /// Position in which `impl Trait` is disallowed. Used for error reporting. #[derive(Debug, Copy, Clone, PartialEq, Eq)] enum ImplTraitPosition { + /// Disallowed in `let` / `const` / `static` bindings. Binding, + + /// All other posiitons. Other, } @@ -223,7 +221,6 @@ impl<'a> ImplTraitContext<'a> { match self { Universal(params) => Universal(params), Existential(fn_def_id) => Existential(*fn_def_id), - AssociatedTy => AssociatedTy, Disallowed(pos) => Disallowed(*pos), } } @@ -256,6 +253,8 @@ pub fn lower_crate( catch_scopes: Vec::new(), loop_scopes: Vec::new(), is_in_loop_condition: false, + is_in_trait_impl: false, + is_in_dyn_type: false, anonymous_lifetime_mode: AnonymousLifetimeMode::PassThrough, type_def_lifetime_params: Default::default(), current_module: CRATE_NODE_ID, @@ -265,7 +264,6 @@ pub fn lower_crate( is_generator: false, is_async_body: false, current_item: None, - is_in_trait_impl: false, lifetimes_to_define: Vec::new(), is_collecting_in_band_lifetimes: false, in_scope_lifetimes: Vec::new(), @@ -1230,6 +1228,20 @@ impl<'a> LoweringContext<'a> { result } + fn with_dyn_type_scope(&mut self, in_scope: bool, f: F) -> T + where + F: FnOnce(&mut LoweringContext<'_>) -> T, + { + let was_in_dyn_type = self.is_in_dyn_type; + self.is_in_dyn_type = in_scope; + + let result = f(self); + + self.is_in_dyn_type = was_in_dyn_type; + + result + } + fn with_new_scopes(&mut self, f: F) -> T where F: FnOnce(&mut LoweringContext<'_>) -> T, @@ -1353,24 +1365,58 @@ impl<'a> LoweringContext<'a> { c: &AssocTyConstraint, itctx: ImplTraitContext<'_>) -> hir::TypeBinding { + debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", c, itctx); + let ty = match c.kind { AssocTyConstraintKind::Equality { ref ty } => self.lower_ty(ty, itctx), AssocTyConstraintKind::Bound { ref bounds } => { - // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. - let impl_ty_node_id = self.sess.next_node_id(); - let parent_def_index = self.current_hir_id_owner.last().unwrap().0; - self.resolver.definitions().create_def_with_parent( - parent_def_index, - impl_ty_node_id, - DefPathData::Misc, - DefIndexAddressSpace::High, - Mark::root(), - DUMMY_SP); - self.lower_ty(&Ty { - id: self.sess.next_node_id(), - node: TyKind::ImplTrait(impl_ty_node_id, bounds.clone()), - span: DUMMY_SP, - }, itctx) + let (existential_desugaring, itctx) = match itctx { + ImplTraitContext::Existential(_) => (true, itctx), + ImplTraitContext::Universal(_) if self.is_in_dyn_type => (true, itctx), + // FIXME: this is only needed until `impl Trait` is allowed in type aliases. + ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => + (true, ImplTraitContext::Existential(None)), + _ => (false, itctx), + }; + + if existential_desugaring { + // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. + + let impl_ty_node_id = self.sess.next_node_id(); + let parent_def_index = self.current_hir_id_owner.last().unwrap().0; + self.resolver.definitions().create_def_with_parent( + parent_def_index, + impl_ty_node_id, + DefPathData::Misc, + DefIndexAddressSpace::High, + Mark::root(), + DUMMY_SP + ); + + self.with_dyn_type_scope(false, |this| { + this.lower_ty( + &Ty { + id: this.sess.next_node_id(), + node: TyKind::ImplTrait(impl_ty_node_id, bounds.clone()), + span: DUMMY_SP, + }, + itctx, + ) + }) + } else { + // Desugar `AssocTy: Bounds` into `AssocTy = ∃ T (T: Bounds)`, where the + // "false existential" later desugars into a trait predicate. + + let bounds = self.lower_param_bounds(bounds, itctx); + + let id = self.sess.next_node_id(); + let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id); + P(hir::Ty { + hir_id, + node: hir::TyKind::AssocTyExistential(bounds), + span: DUMMY_SP, + }) + } } }; @@ -1477,23 +1523,26 @@ impl<'a> LoweringContext<'a> { } TyKind::TraitObject(ref bounds, kind) => { let mut lifetime_bound = None; - let bounds = bounds - .iter() - .filter_map(|bound| match *bound { - GenericBound::Trait(ref ty, TraitBoundModifier::None) => { - Some(self.lower_poly_trait_ref(ty, itctx.reborrow())) - } - GenericBound::Trait(_, TraitBoundModifier::Maybe) => None, - GenericBound::Outlives(ref lifetime) => { - if lifetime_bound.is_none() { - lifetime_bound = Some(self.lower_lifetime(lifetime)); + let (bounds, lifetime_bound) = self.with_dyn_type_scope(true, |this| { + let bounds = bounds + .iter() + .filter_map(|bound| match *bound { + GenericBound::Trait(ref ty, TraitBoundModifier::None) => { + Some(this.lower_poly_trait_ref(ty, itctx.reborrow())) } - None - } - }) - .collect(); - let lifetime_bound = - lifetime_bound.unwrap_or_else(|| self.elided_dyn_bound(t.span)); + GenericBound::Trait(_, TraitBoundModifier::Maybe) => None, + GenericBound::Outlives(ref lifetime) => { + if lifetime_bound.is_none() { + lifetime_bound = Some(this.lower_lifetime(lifetime)); + } + None + } + }) + .collect(); + let lifetime_bound = + lifetime_bound.unwrap_or_else(|| this.elided_dyn_bound(t.span)); + (bounds, lifetime_bound) + }); if kind != TraitObjectSyntax::Dyn { self.maybe_lint_bare_trait(t.span, t.id, false); } @@ -1544,16 +1593,6 @@ impl<'a> LoweringContext<'a> { }), )) } - ImplTraitContext::AssociatedTy => { - let hir_bounds = self.lower_param_bounds( - bounds, - ImplTraitContext::AssociatedTy, - ); - - hir::TyKind::AssocTyExistential( - hir_bounds, - ) - } ImplTraitContext::Disallowed(pos) => { let allowed_in = if self.sess.features_untracked() .impl_trait_in_bindings { @@ -2407,7 +2446,8 @@ impl<'a> LoweringContext<'a> { FunctionRetTy::Ty(ref ty) => match in_band_ty_params { Some((def_id, _)) if impl_trait_return_allow => { hir::Return(self.lower_ty(ty, - ImplTraitContext::Existential(Some(def_id)))) + ImplTraitContext::Existential(Some(def_id)) + )) } _ => { hir::Return(self.lower_ty(ty, ImplTraitContext::disallowed())) @@ -2770,7 +2810,7 @@ impl<'a> LoweringContext<'a> { let kind = hir::GenericParamKind::Type { default: default.as_ref().map(|x| { - self.lower_ty(x, ImplTraitContext::disallowed()) + self.lower_ty(x, ImplTraitContext::Existential(None)) }), synthetic: param.attrs.iter() .filter(|attr| attr.check_name(sym::rustc_synthetic)) @@ -3275,39 +3315,43 @@ impl<'a> LoweringContext<'a> { ItemKind::ForeignMod(ref nm) => hir::ItemKind::ForeignMod(self.lower_foreign_mod(nm)), ItemKind::GlobalAsm(ref ga) => hir::ItemKind::GlobalAsm(self.lower_global_asm(ga)), ItemKind::Ty(ref t, ref generics) => hir::ItemKind::Ty( - self.lower_ty(t, ImplTraitContext::AssociatedTy), - self.lower_generics(generics, ImplTraitContext::AssociatedTy), + self.lower_ty(t, ImplTraitContext::disallowed()), + self.lower_generics(generics, ImplTraitContext::disallowed()), ), ItemKind::Existential(ref b, ref generics) => hir::ItemKind::Existential( hir::ExistTy { - generics: self.lower_generics(generics, ImplTraitContext::AssociatedTy), - bounds: self.lower_param_bounds(b, ImplTraitContext::AssociatedTy), + generics: self.lower_generics(generics, + ImplTraitContext::Existential(None)), + bounds: self.lower_param_bounds(b, + ImplTraitContext::Existential(None)), impl_trait_fn: None, origin: hir::ExistTyOrigin::ExistentialType, }, ), - ItemKind::Enum(ref enum_definition, ref generics) => hir::ItemKind::Enum( - hir::EnumDef { - variants: enum_definition - .variants - .iter() - .map(|x| self.lower_variant(x)) - .collect(), - }, - self.lower_generics(generics, ImplTraitContext::AssociatedTy), - ), + ItemKind::Enum(ref enum_definition, ref generics) => { + hir::ItemKind::Enum( + hir::EnumDef { + variants: enum_definition + .variants + .iter() + .map(|x| self.lower_variant(x)) + .collect(), + }, + self.lower_generics(generics, ImplTraitContext::disallowed()), + ) + }, ItemKind::Struct(ref struct_def, ref generics) => { let struct_def = self.lower_variant_data(struct_def); hir::ItemKind::Struct( struct_def, - self.lower_generics(generics, ImplTraitContext::AssociatedTy), + self.lower_generics(generics, ImplTraitContext::disallowed()), ) } ItemKind::Union(ref vdata, ref generics) => { let vdata = self.lower_variant_data(vdata); hir::ItemKind::Union( vdata, - self.lower_generics(generics, ImplTraitContext::AssociatedTy), + self.lower_generics(generics, ImplTraitContext::disallowed()), ) } ItemKind::Impl( @@ -3675,9 +3719,9 @@ impl<'a> LoweringContext<'a> { (generics, hir::TraitItemKind::Method(sig, hir::TraitMethod::Provided(body_id))) } TraitItemKind::Type(ref bounds, ref default) => { - let generics = self.lower_generics(&i.generics, ImplTraitContext::AssociatedTy); + let generics = self.lower_generics(&i.generics, ImplTraitContext::disallowed()); let node = hir::TraitItemKind::Type( - self.lower_param_bounds(bounds, ImplTraitContext::AssociatedTy), + self.lower_param_bounds(bounds, ImplTraitContext::disallowed()), default .as_ref() .map(|x| self.lower_ty(x, ImplTraitContext::disallowed())), diff --git a/src/librustc_passes/ast_validation.rs b/src/librustc_passes/ast_validation.rs index 2d602a7f1b468..532cec2af159e 100644 --- a/src/librustc_passes/ast_validation.rs +++ b/src/librustc_passes/ast_validation.rs @@ -63,6 +63,10 @@ struct AstValidator<'a> { /// or `Foo::Bar` is_impl_trait_banned: bool, + /// Used to ban associated type bounds (i.e., `Type`) in + /// certain positions. + is_assoc_ty_bound_banned: bool, + /// rust-lang/rust#57979: the ban of nested `impl Trait` was buggy /// until PRs #57730 and #57981 landed: it would jump directly to /// walk_ty rather than visit_ty (or skip recurring entirely for @@ -87,6 +91,12 @@ impl<'a> AstValidator<'a> { self.is_impl_trait_banned = old; } + fn with_banned_assoc_ty_bound(&mut self, f: impl FnOnce(&mut Self)) { + let old = mem::replace(&mut self.is_assoc_ty_bound_banned, true); + f(self); + self.is_assoc_ty_bound_banned = old; + } + fn with_impl_trait(&mut self, outer: Option, f: impl FnOnce(&mut Self)) { let old = mem::replace(&mut self.outer_impl_trait, outer); f(self); @@ -94,12 +104,21 @@ impl<'a> AstValidator<'a> { } fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) { - if let AssocTyConstraintKind::Equality { ref ty } = constraint.kind { - // rust-lang/rust#57979: bug in old `visit_generic_args` called - // `walk_ty` rather than `visit_ty`, skipping outer `impl Trait` - // if it happened to occur at `ty`. - if let TyKind::ImplTrait(..) = ty.node { - self.warning_period_57979_didnt_record_next_impl_trait = true; + match constraint.kind { + AssocTyConstraintKind::Equality { ref ty } => { + // rust-lang/rust#57979: bug in old `visit_generic_args` called + // `walk_ty` rather than `visit_ty`, skipping outer `impl Trait` + // if it happened to occur at `ty`. + if let TyKind::ImplTrait(..) = ty.node { + self.warning_period_57979_didnt_record_next_impl_trait = true; + } + } + AssocTyConstraintKind::Bound { .. } => { + if self.is_assoc_ty_bound_banned { + self.err_handler().span_err(constraint.span, + "associated type bounds are not allowed within structs, enums, or unions" + ); + } } } self.visit_assoc_ty_constraint(constraint); @@ -726,7 +745,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> { // Type bindings such as `Item = impl Debug` in `Iterator` // are allowed to contain nested `impl Trait`. self.with_impl_trait(None, |this| { - walk_list!(this, visit_assoc_ty_constraint_from_generic_args, &data.constraints); + walk_list!(this, visit_assoc_ty_constraint_from_generic_args, + &data.constraints); }); } GenericArgs::Parenthesized(ref data) => { @@ -819,6 +839,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> { visit::walk_poly_trait_ref(self, t, m); } + fn visit_variant_data(&mut self, s: &'a VariantData, _: Ident, + _: &'a Generics, _: NodeId, _: Span) { + self.with_banned_assoc_ty_bound(|this| visit::walk_struct_def(this, s)) + } + + fn visit_enum_def(&mut self, enum_definition: &'a EnumDef, + generics: &'a Generics, item_id: NodeId, _: Span) { + self.with_banned_assoc_ty_bound( + |this| visit::walk_enum_def(this, enum_definition, generics, item_id)) + } + fn visit_mac(&mut self, mac: &Spanned) { // when a new macro kind is added but the author forgets to set it up for expansion // because that's the only part that won't cause a compiler error @@ -842,6 +873,7 @@ pub fn check_crate(session: &Session, krate: &Crate) -> (bool, bool) { has_global_allocator: false, outer_impl_trait: None, is_impl_trait_banned: false, + is_assoc_ty_bound_banned: false, warning_period_57979_didnt_record_next_impl_trait: false, warning_period_57979_impl_trait_in_proj: false, }; diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 6123ee2af6e88..5ddb2c974ac02 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -930,13 +930,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { .into_iter() .map(|r| (self.ast_region_to_region(r, None), r.span)) ); - - bounds.trait_bounds.sort_by_key(|(t, _)| t.def_id()); } - /// Translates the AST's notion of ty param bounds (which are an enum consisting of a newtyped `Ty` - /// or a region) to ty's notion of ty param bounds, which can either be user-defined traits or the - /// built-in trait `Send`. + /// Translates the AST's notion of ty param bounds (which are an enum consisting of a newtyped + /// `Ty` or a region) to ty's notion of ty param bounds, which can either be user-defined traits + /// or the built-in trait `Send`. pub fn compute_bounds(&self, param_ty: Ty<'tcx>, ast_bounds: &[hir::GenericBound], @@ -944,7 +942,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { span: Span, ) -> Bounds<'tcx> { let mut bounds = Bounds::default(); + self.add_bounds(param_ty, ast_bounds, &mut bounds); + bounds.trait_bounds.sort_by_key(|(t, _)| t.def_id()); + bounds.implicitly_sized = if let SizedByDefault::Yes = sized_by_default { if !self.is_unsized(ast_bounds, span) { Some(span) @@ -954,6 +955,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else { None }; + bounds } @@ -993,7 +995,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // for<'a> ::Item = &'a str // <-- 'a is bad // for<'a> >::Output = &'a str // <-- 'a is ok if let ConvertedBindingKind::Equality(ty) = binding.kind { - let late_bound_in_trait_ref = tcx.collect_constrained_late_bound_regions(&trait_ref); + let late_bound_in_trait_ref = + tcx.collect_constrained_late_bound_regions(&trait_ref); let late_bound_in_ty = tcx.collect_referenced_late_bound_regions(&ty::Binder::bind(ty)); debug!("late_bound_in_trait_ref = {:?}", late_bound_in_trait_ref); @@ -1074,8 +1077,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }), binding.span)); } ConvertedBindingKind::Constraint(ref ast_bounds) => { + // Calling `skip_binder` is okay, because the predicates are re-bound later by + // `instantiate_poly_trait_ref`. + let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs); self.add_bounds( - trait_ref.self_ty(), + param_ty, ast_bounds, bounds, ); @@ -2050,6 +2056,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } }; + debug!("ast_ty_to_ty: result_ty={:?}", result_ty); + self.record_ty(ast_ty.hir_id, result_ty, ast_ty.span); result_ty } @@ -2135,7 +2143,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } } }); - debug!("impl_trait_ty_to_ty: final substs = {:?}", substs); + debug!("impl_trait_ty_to_ty: substs={:?}", substs); let ty = tcx.mk_opaque(def_id, substs); debug!("impl_trait_ty_to_ty: {}", ty); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 92d0e37cb9bbd..90ab596363bff 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -703,7 +703,8 @@ fn super_predicates_of<'a, 'tcx>( // Convert the bounds that follow the colon, e.g., `Bar + Zed` in `trait Foo: Bar + Zed`. let self_param_ty = tcx.mk_self_type(); - let superbounds1 = AstConv::compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, item.span); + let superbounds1 = AstConv::compute_bounds(&icx, self_param_ty, bounds, SizedByDefault::No, + item.span); let superbounds1 = superbounds1.predicates(tcx, self_param_ty); @@ -1988,15 +1989,16 @@ fn explicit_predicates_of<'a, 'tcx>( tcx.def_span(def_id), ); + let bounds_predicates = bounds.predicates(tcx, opaque_ty); if impl_trait_fn.is_some() { // opaque types return tcx.arena.alloc(ty::GenericPredicates { parent: None, - predicates: bounds.predicates(tcx, opaque_ty), + predicates: bounds_predicates, }); } else { // named existential types - predicates.extend(bounds.predicates(tcx, opaque_ty)); + predicates.extend(bounds_predicates); generics } } From cad1b1847eb6c2b720858f26af16d38d658fbc1a Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 21 Mar 2019 18:40:00 +0000 Subject: [PATCH 06/24] Added feature gate. --- src/librustc/hir/lowering.rs | 2 +- src/libsyntax/feature_gate.rs | 42 +++++++++++++++++++++++++---------- 2 files changed, 31 insertions(+), 13 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 165723bcfa278..eab01c0bf9924 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -200,7 +200,7 @@ enum ImplTraitContext<'a> { Disallowed(ImplTraitPosition), } -/// Position in which `impl Trait` is disallowed. Used for error reporting. +/// Position in which `impl Trait` is disallowed. #[derive(Debug, Copy, Clone, PartialEq, Eq)] enum ImplTraitPosition { /// Disallowed in `let` / `const` / `static` bindings. diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index b2646efe3e464..4a95b6f69a161 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -15,7 +15,10 @@ use AttributeType::*; use AttributeGate::*; -use crate::ast::{self, NodeId, GenericParam, GenericParamKind, PatKind, RangeEnd}; +use crate::ast::{ + self, AssocTyConstraint, AssocTyConstraintKind, NodeId, GenericParam, GenericParamKind, + PatKind, RangeEnd, +}; use crate::attr; use crate::early_buffered_lints::BufferedEarlyLintId; use crate::source_map::Spanned; @@ -554,6 +557,9 @@ declare_features! ( // Allows using C-variadics. (active, c_variadic, "1.34.0", Some(44930), None), + // Allows the user of associated type bounds. + (active, associated_type_bounds, "1.34.0", Some(52662), None), + // ------------------------------------------------------------------------- // feature-group-end: actual feature gates // ------------------------------------------------------------------------- @@ -1917,7 +1923,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { self.builtin_attributes.get(&ident.name).map(|a| *a) }); - // check for gated attributes + // Check for gated attributes. self.context.check_attribute(attr, attr_info, false); if attr.check_name(sym::doc) { @@ -2115,7 +2121,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) { if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty { if let ast::TyKind::Never = output_ty.node { - // Do nothing + // Do nothing. } else { self.visit_ty(output_ty) } @@ -2171,7 +2177,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } _ => {} } - visit::walk_expr(self, e); + visit::walk_expr(self, e) } fn visit_arm(&mut self, arm: &'a ast::Arm) { @@ -2220,15 +2226,27 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, c_variadic, span, "C-variadic functions are unstable"); } - visit::walk_fn(self, fn_kind, fn_decl, span); + visit::walk_fn(self, fn_kind, fn_decl, span) } fn visit_generic_param(&mut self, param: &'a GenericParam) { - if let GenericParamKind::Const { .. } = param.kind { - gate_feature_post!(&self, const_generics, param.ident.span, - "const generics are unstable"); + match param.kind { + GenericParamKind::Const { .. } => + gate_feature_post!(&self, const_generics, param.ident.span, + "const generics are unstable"), + _ => {} + } + visit::walk_generic_param(self, param) + } + + fn visit_assoc_ty_constraint(&mut self, constraint: &'a AssocTyConstraint) { + match constraint.kind { + AssocTyConstraintKind::Bound { .. } => + gate_feature_post!(&self, associated_type_bounds, constraint.span, + "associated type bounds are unstable"), + _ => {} } - visit::walk_generic_param(self, param); + visit::walk_assoc_ty_constraint(self, constraint) } fn visit_trait_item(&mut self, ti: &'a ast::TraitItem) { @@ -2266,7 +2284,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } _ => {} } - visit::walk_trait_item(self, ti); + visit::walk_trait_item(self, ti) } fn visit_impl_item(&mut self, ii: &'a ast::ImplItem) { @@ -2298,7 +2316,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } _ => {} } - visit::walk_impl_item(self, ii); + visit::walk_impl_item(self, ii) } fn visit_vis(&mut self, vis: &'a ast::Visibility) { @@ -2306,7 +2324,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { gate_feature_post!(&self, crate_visibility_modifier, vis.span, "`crate` visibility modifier is experimental"); } - visit::walk_vis(self, vis); + visit::walk_vis(self, vis) } } From 4310ba2c985c161260bbdfef5d92ceea552e9055 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 16 Mar 2019 00:03:51 +0000 Subject: [PATCH 07/24] Added test suite. --- src/test/run-pass/issues/issue-25700-2.rs | 2 +- .../auxiliary/fn-aux.rs | 177 +++++ .../auxiliary/fn-dyn-aux.rs | 182 +++++ .../bad-bounds-on-assoc-in-trait.rs | 60 ++ .../bad-bounds-on-assoc-in-trait.stderr | 85 +++ .../bounds-on-assoc-in-trait.rs | 51 ++ .../ui/associated-type-bounds/duplicate.rs | 161 +++++ .../associated-type-bounds/duplicate.stderr | 627 ++++++++++++++++++ .../dyn-existential-type.rs | 67 ++ .../ui/associated-type-bounds/dyn-lcsit.rs | 69 ++ .../dyn-rpit-and-let.rs | 73 ++ .../entails-sized-object-safety.rs | 26 + .../ui/associated-type-bounds/enum-bounds.rs | 122 ++++ .../existential-type.rs | 67 ++ src/test/ui/associated-type-bounds/fn-apit.rs | 58 ++ src/test/ui/associated-type-bounds/fn-aux.rs | 12 + .../ui/associated-type-bounds/fn-dyn-apit.rs | 60 ++ .../ui/associated-type-bounds/fn-inline.rs | 62 ++ .../ui/associated-type-bounds/fn-where.rs | 78 +++ .../ui/associated-type-bounds/fn-wrap-apit.rs | 64 ++ .../implied-region-constraints.rs | 47 ++ .../implied-region-constraints.stderr | 25 + .../ui/associated-type-bounds/inside-adt.rs | 36 + .../associated-type-bounds/inside-adt.stderr | 79 +++ src/test/ui/associated-type-bounds/lcsit.rs | 78 +++ .../nested-lifetime-bounds.rs | 25 + .../nested-lifetime-bounds.stderr | 9 + src/test/ui/associated-type-bounds/rpit.rs | 64 ++ .../associated-type-bounds/struct-bounds.rs | 115 ++++ .../ui/associated-type-bounds/trait-params.rs | 116 ++++ .../ui/associated-type-bounds/type-alias.rs | 19 + .../associated-type-bounds/type-alias.stderr | 97 +++ .../ui/associated-type-bounds/union-bounds.rs | 123 ++++ .../feature-gate-associated_type_bounds.rs | 71 ++ ...feature-gate-associated_type_bounds.stderr | 132 ++++ src/test/ui/type/type-alias-bounds.stderr | 10 - 36 files changed, 3138 insertions(+), 11 deletions(-) create mode 100644 src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs create mode 100644 src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs create mode 100644 src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs create mode 100644 src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr create mode 100644 src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs create mode 100644 src/test/ui/associated-type-bounds/duplicate.rs create mode 100644 src/test/ui/associated-type-bounds/duplicate.stderr create mode 100644 src/test/ui/associated-type-bounds/dyn-existential-type.rs create mode 100644 src/test/ui/associated-type-bounds/dyn-lcsit.rs create mode 100644 src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs create mode 100644 src/test/ui/associated-type-bounds/entails-sized-object-safety.rs create mode 100644 src/test/ui/associated-type-bounds/enum-bounds.rs create mode 100644 src/test/ui/associated-type-bounds/existential-type.rs create mode 100644 src/test/ui/associated-type-bounds/fn-apit.rs create mode 100644 src/test/ui/associated-type-bounds/fn-aux.rs create mode 100644 src/test/ui/associated-type-bounds/fn-dyn-apit.rs create mode 100644 src/test/ui/associated-type-bounds/fn-inline.rs create mode 100644 src/test/ui/associated-type-bounds/fn-where.rs create mode 100644 src/test/ui/associated-type-bounds/fn-wrap-apit.rs create mode 100644 src/test/ui/associated-type-bounds/implied-region-constraints.rs create mode 100644 src/test/ui/associated-type-bounds/implied-region-constraints.stderr create mode 100644 src/test/ui/associated-type-bounds/inside-adt.rs create mode 100644 src/test/ui/associated-type-bounds/inside-adt.stderr create mode 100644 src/test/ui/associated-type-bounds/lcsit.rs create mode 100644 src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs create mode 100644 src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr create mode 100644 src/test/ui/associated-type-bounds/rpit.rs create mode 100644 src/test/ui/associated-type-bounds/struct-bounds.rs create mode 100644 src/test/ui/associated-type-bounds/trait-params.rs create mode 100644 src/test/ui/associated-type-bounds/type-alias.rs create mode 100644 src/test/ui/associated-type-bounds/type-alias.stderr create mode 100644 src/test/ui/associated-type-bounds/union-bounds.rs create mode 100644 src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs create mode 100644 src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr diff --git a/src/test/run-pass/issues/issue-25700-2.rs b/src/test/run-pass/issues/issue-25700-2.rs index 65de5edce48dd..b161e68abafd0 100644 --- a/src/test/run-pass/issues/issue-25700-2.rs +++ b/src/test/run-pass/issues/issue-25700-2.rs @@ -18,5 +18,5 @@ fn record_type(i: Id::Untyped) -> u8 { } pub fn main() { - assert_eq!(record_type::(3), 42); + assert_eq!(record_type::(3), 42); } diff --git a/src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs b/src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs new file mode 100644 index 0000000000000..0ea23ad1dbffa --- /dev/null +++ b/src/test/ui/associated-type-bounds/auxiliary/fn-aux.rs @@ -0,0 +1,177 @@ +// Traits: + +pub trait Alpha { + fn alpha(self) -> usize; +} + +pub trait Beta { + type Gamma; + fn gamma(self) -> Self::Gamma; +} + +pub trait Delta { + fn delta(self) -> usize; +} + +pub trait Epsilon<'a> { + type Zeta; + fn zeta(&'a self) -> Self::Zeta; + + fn epsilon(&'a self) -> usize; +} + +pub trait Eta { + fn eta(self) -> usize; +} + +// Assertions: + +pub fn assert_alpha(x: T) -> usize { x.alpha() } +pub fn assert_static(_: T) -> usize { 24 } +pub fn assert_delta(x: T) -> usize { x.delta() } +pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() } +pub fn assert_epsilon_forall Epsilon<'a>>() {} +pub fn assert_forall_epsilon_zeta_satisfies_eta(x: T) -> usize +where + T: for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + x.epsilon() + x.zeta().eta() +} + +// Implementations and types: + +#[derive(Copy, Clone)] +pub struct BetaType; + +#[derive(Copy, Clone)] +pub struct GammaType; + +#[derive(Copy, Clone)] +pub struct ZetaType; + +impl Beta for BetaType { + type Gamma = GammaType; + fn gamma(self) -> Self::Gamma { GammaType } +} + +impl<'a> Beta for &'a BetaType { + type Gamma = GammaType; + fn gamma(self) -> Self::Gamma { GammaType } +} + +impl Beta for GammaType { + type Gamma = Self; + fn gamma(self) -> Self::Gamma { self } +} + +impl Alpha for GammaType { + fn alpha(self) -> usize { 42 } +} + +impl Delta for GammaType { + fn delta(self) -> usize { 1337 } +} + +impl<'a> Epsilon<'a> for GammaType { + type Zeta = ZetaType; + fn zeta(&'a self) -> Self::Zeta { ZetaType } + + fn epsilon(&'a self) -> usize { 7331 } +} + +impl Eta for ZetaType { + fn eta(self) -> usize { 7 } +} + +// Desugared forms to check against: + +pub fn desugared_bound(beta: B) -> usize +where + B: Beta, + B::Gamma: Alpha +{ + let gamma: B::Gamma = beta.gamma(); + assert_alpha::(gamma) +} + +pub fn desugared_bound_region(beta: B) -> usize +where + B: Beta, + B::Gamma: 'static, +{ + assert_static::(beta.gamma()) +} + +pub fn desugared_bound_multi(beta: B) -> usize +where + B: Copy + Beta, + B::Gamma: Alpha + 'static + Delta, +{ + assert_alpha::(beta.gamma()) + + assert_static::(beta.gamma()) + + assert_delta::(beta.gamma()) +} + +pub fn desugared_bound_region_specific<'a, B>(gamma: &'a B::Gamma) -> usize +where + B: Beta, + B::Gamma: 'a + Epsilon<'a>, +{ + assert_epsilon_specific::(gamma) +} + +pub fn desugared_bound_region_forall(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, +{ + assert_epsilon_forall::(); + let g1: B::Gamma = beta.gamma(); + let g2: B::Gamma = g1; + assert_epsilon_specific::(&g1) + + assert_epsilon_specific::(&g2) +} + +pub fn desugared_bound_region_forall2(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + let gamma = beta.gamma(); + assert_forall_epsilon_zeta_satisfies_eta::(gamma) +} + +pub fn desugared_contraint_region_forall(beta: B) -> usize +where + for<'a> &'a B: Beta, + for<'a> <&'a B as Beta>::Gamma: Alpha, +{ + let g1 = beta.gamma(); + let g2 = beta.gamma(); + assert_alpha(g1) + assert_alpha(g2) +} + +pub fn desugared_bound_nested(beta: B) -> usize +where + B: Beta, + B::Gamma: Copy + Alpha + Beta, + ::Gamma: Delta, +{ + let go = beta.gamma(); + let gi = go.gamma(); + go.alpha() + gi.delta() +} + +pub fn desugared() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, desugared_bound(beta)); + assert_eq!(24, desugared_bound_region(beta)); + assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta)); + assert_eq!(7331, desugared_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, desugared_bound_region_forall(beta)); + assert_eq!(42 + 1337, desugared_bound_nested(beta)); +} diff --git a/src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs b/src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs new file mode 100644 index 0000000000000..85d6c5aaf3c6f --- /dev/null +++ b/src/test/ui/associated-type-bounds/auxiliary/fn-dyn-aux.rs @@ -0,0 +1,182 @@ +// Traits: + +pub trait Alpha { + fn alpha(self) -> usize; +} + +pub trait Beta { + type Gamma; + fn gamma(&self) -> Self::Gamma; +} + +pub trait Delta { + fn delta(self) -> usize; +} + +pub trait Epsilon<'a> { + type Zeta; + fn zeta(&'a self) -> Self::Zeta; + + fn epsilon(&'a self) -> usize; +} + +pub trait Eta { + fn eta(self) -> usize; +} + +// Assertions: + +pub fn assert_alpha(x: T) -> usize { x.alpha() } +pub fn assert_static(_: T) -> usize { 24 } +pub fn assert_delta(x: T) -> usize { x.delta() } +pub fn assert_epsilon_specific<'a, T: 'a + Epsilon<'a>>(x: &'a T) -> usize { x.epsilon() } +pub fn assert_epsilon_forall Epsilon<'a>>() {} +pub fn assert_forall_epsilon_zeta_satisfies_eta(x: T) -> usize +where + T: for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + x.epsilon() + x.zeta().eta() +} + +// Implementations and types: + +#[derive(Copy, Clone)] +pub struct BetaType; + +#[derive(Copy, Clone)] +pub struct GammaType; + +#[derive(Copy, Clone)] +pub struct ZetaType; + +impl Beta for &(dyn Beta + Send) { + type Gamma = T; + fn gamma(&self) -> Self::Gamma { (*self).gamma() } +} + +impl Beta for BetaType { + type Gamma = GammaType; + fn gamma(&self) -> Self::Gamma { GammaType } +} + +impl<'a> Beta for &'a BetaType { + type Gamma = GammaType; + fn gamma(&self) -> Self::Gamma { GammaType } +} + +impl Beta for GammaType { + type Gamma = Self; + fn gamma(&self) -> Self::Gamma { Self } +} + +impl Alpha for GammaType { + fn alpha(self) -> usize { 42 } +} + +impl Delta for GammaType { + fn delta(self) -> usize { 1337 } +} + +impl<'a> Epsilon<'a> for GammaType { + type Zeta = ZetaType; + fn zeta(&'a self) -> Self::Zeta { ZetaType } + + fn epsilon(&'a self) -> usize { 7331 } +} + +impl Eta for ZetaType { + fn eta(self) -> usize { 7 } +} + +// Desugared forms to check against: + +pub fn desugared_bound(beta: &B) -> usize +where + B: Beta, + B::Gamma: Alpha +{ + let gamma: B::Gamma = beta.gamma(); + assert_alpha::(gamma) +} + +pub fn desugared_bound_region(beta: &B) -> usize +where + B: Beta, + B::Gamma: 'static, +{ + assert_static::(beta.gamma()) +} + +pub fn desugared_bound_multi(beta: B) -> usize +where + B: Copy + Beta, + B::Gamma: Alpha + 'static + Delta, +{ + assert_alpha::(beta.gamma()) + + assert_static::(beta.gamma()) + + assert_delta::(beta.gamma()) +} + +pub fn desugared_bound_region_specific<'a, B: ?Sized>(gamma: &'a B::Gamma) -> usize +where + B: Beta, + B::Gamma: 'a + Epsilon<'a>, +{ + assert_epsilon_specific::(gamma) +} + +pub fn desugared_bound_region_forall(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, +{ + assert_epsilon_forall::(); + let g1: B::Gamma = beta.gamma(); + let g2: B::Gamma = g1; + assert_epsilon_specific::(&g1) + + assert_epsilon_specific::(&g2) +} + +pub fn desugared_bound_region_forall2(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + for<'a> Epsilon<'a>, + for<'a> >::Zeta: Eta, +{ + let gamma = beta.gamma(); + assert_forall_epsilon_zeta_satisfies_eta::(gamma) +} + +pub fn desugared_contraint_region_forall(beta: &B) -> usize +where + for<'a> &'a B: Beta, + for<'a> <&'a B as Beta>::Gamma: Alpha, +{ + let g1 = beta.gamma(); + let g2 = beta.gamma(); + assert_alpha(g1) + assert_alpha(g2) +} + +pub fn desugared_bound_nested(beta: &B) -> usize +where + B: Beta, + B::Gamma: Copy + Alpha + Beta, + ::Gamma: Delta, +{ + let go = beta.gamma(); + let gi = go.gamma(); + go.alpha() + gi.delta() +} + +pub fn desugared() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, desugared_bound(&beta)); + assert_eq!(24, desugared_bound_region(&beta)); + assert_eq!(42 + 24 + 1337, desugared_bound_multi(beta)); + assert_eq!(7331, desugared_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, desugared_bound_region_forall(&beta)); + assert_eq!(42 + 1337, desugared_bound_nested(&beta)); +} diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs new file mode 100644 index 0000000000000..78704a9b51239 --- /dev/null +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.rs @@ -0,0 +1,60 @@ +// compile-fail +// ignore-tidy-linelength + +// NOTE: rustc cannot currently handle bounds of the form `for<'a> >::Assoc: Baz`. +// This should hopefully be fixed with Chalk. + +#![feature(associated_type_bounds)] + +use std::fmt::Debug; +use std::iter::Once; + +trait Lam { type App; } + +#[derive(Clone)] +struct L1; +impl<'a> Lam<&'a u8> for L1 { type App = u8; } + +#[derive(Clone)] +struct L2; +impl<'a, 'b> Lam<&'a &'b u8> for L2 { type App = u8; } + +trait Case1 { + type C: Clone + Iterator Lam<&'a u8, App: + Debug + > + > + Sync>; +} + +pub struct S1; +impl Case1 for S1 { +//~^ ERROR `>::App` doesn't implement `std::fmt::Debug` [E0277] + type C = Once>; +} + +fn assume_case1() { +//~^ ERROR `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` [E0277] +//~| ERROR `<::C as std::iter::Iterator>::Item` is not an iterator [E0277] +//~| ERROR `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely [E0277] +//~| ERROR `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely [E0277] + fn assert_a<_0, A>() where A: Iterator, _0: Debug {} + assert_a::<_, T::A>(); + + fn assert_b<_0, B>() where B: Iterator, _0: 'static {} + assert_b::<_, T::B>(); + + fn assert_c<_0, _1, _2, C>() + where + C: Clone + Iterator, + _2: Send + Iterator, + _1: for<'a> Lam<&'a u8, App = _0>, + _0: Debug, + {} + assert_c::<_, _, _, T::C>(); +} + +fn main() { + assume_case1(S1); +} diff --git a/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr new file mode 100644 index 0000000000000..aebf29cc332ab --- /dev/null +++ b/src/test/ui/associated-type-bounds/bad-bounds-on-assoc-in-trait.stderr @@ -0,0 +1,85 @@ +error[E0277]: `>::App` doesn't implement `std::fmt::Debug` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:32:6 + | +LL | impl Case1 for S1 { + | ^^^^^ `>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `for<'a> std::fmt::Debug` is not implemented for `>::App` + +error[E0277]: `<::C as std::iter::Iterator>::Item` is not an iterator + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<::C as std::iter::Iterator>::Item` is not an iterator + | + = help: the trait `std::iter::Iterator` is not implemented for `<::C as std::iter::Iterator>::Item` + = help: consider adding a `where <::C as std::iter::Iterator>::Item: std::iter::Iterator` bound + +error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<::C as std::iter::Iterator>::Item` cannot be sent between threads safely + | + = help: the trait `std::marker::Send` is not implemented for `<::C as std::iter::Iterator>::Item` + = help: consider adding a `where <::C as std::iter::Iterator>::Item: std::marker::Send` bound +note: required by `Case1` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1 + | +LL | trait Case1 { + | ^^^^^^^^^^^ + +error[E0277]: `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<::C as std::iter::Iterator>::Item` cannot be shared between threads safely + | + = help: the trait `std::marker::Sync` is not implemented for `<::C as std::iter::Iterator>::Item` + = help: consider adding a `where <::C as std::iter::Iterator>::Item: std::marker::Sync` bound +note: required by `Case1` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1 + | +LL | trait Case1 { + | ^^^^^^^^^^^ + +error[E0277]: `<_ as Lam<&'a u8>>::App` doesn't implement `std::fmt::Debug` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:37:1 + | +LL | / fn assume_case1() { +LL | | +LL | | +LL | | +... | +LL | | assert_c::<_, _, _, T::C>(); +LL | | } + | |_^ `<_ as Lam<&'a u8>>::App` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `for<'a> std::fmt::Debug` is not implemented for `<_ as Lam<&'a u8>>::App` +note: required by `Case1` + --> $DIR/bad-bounds-on-assoc-in-trait.rs:22:1 + | +LL | trait Case1 { + | ^^^^^^^^^^^ + +error: aborting due to 5 previous errors + +For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs new file mode 100644 index 0000000000000..8c9110d03ec16 --- /dev/null +++ b/src/test/ui/associated-type-bounds/bounds-on-assoc-in-trait.rs @@ -0,0 +1,51 @@ +// run-pass + +#![feature(associated_type_bounds)] + +use std::fmt::Debug; +use std::iter::Empty; +use std::ops::Range; + +trait Lam { type App; } + +#[derive(Clone)] +struct L1; +impl<'a> Lam<&'a u8> for L1 { type App = u8; } + +#[derive(Clone)] +struct L2; +impl<'a, 'b> Lam<&'a &'b u8> for L2 { type App = u8; } + +trait Case1 { + type A: Iterator; + + type B: Iterator; +} + +pub struct S1; +impl Case1 for S1 { + type A = Empty; + type B = Range; +} + +// Ensure we don't have existential desugaring: + +pub trait Foo { type Out: Baz; } +pub trait Baz { type Assoc; } + +#[derive(Default)] +struct S2; +#[derive(Default)] +struct S3; +struct S4; +struct S5; +struct S6; +struct S7; + +impl Foo for S6 { type Out = S4; } +impl Foo for S7 { type Out = S5; } + +impl Baz for S4 { type Assoc = S2; } +impl Baz for S5 { type Assoc = S3; } + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/duplicate.rs b/src/test/ui/associated-type-bounds/duplicate.rs new file mode 100644 index 0000000000000..bee56d6f68990 --- /dev/null +++ b/src/test/ui/associated-type-bounds/duplicate.rs @@ -0,0 +1,161 @@ +// compile-fail +// ignore-tidy-linelength +// error-pattern:could not find defining uses + +#![feature(associated_type_bounds)] +#![feature(existential_type)] +#![feature(impl_trait_in_bindings)] +#![feature(untagged_unions)] + +use std::iter; + +struct SI1> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SI2> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SI3> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SW1 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SW2 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +struct SW3 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +enum EI1> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EI2> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EI3> { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EW1 where T: Iterator { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EW2 where T: Iterator { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +enum EW3 where T: Iterator { V(T) } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +union UI1> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UI2> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UI3> { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UW1 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UW2 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +union UW3 where T: Iterator { f: T } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn FI1>() {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FI2>() {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FI3>() {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FW1() where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FW2() where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FW3() where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn FRPIT1() -> impl Iterator { iter::empty() } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FRPIT2() -> impl Iterator { iter::empty() } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FRPIT3() -> impl Iterator { iter::empty() } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FAPIT1(_: impl Iterator) {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FAPIT2(_: impl Iterator) {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn FAPIT3(_: impl Iterator) {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +const CIT1: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +const CIT2: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +const CIT3: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +static SIT1: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +static SIT2: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +static SIT3: impl Iterator = iter::empty(); +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn lit1() { let _: impl Iterator = iter::empty(); } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn lit2() { let _: impl Iterator = iter::empty(); } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +fn lit3() { let _: impl Iterator = iter::empty(); } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +type TAI1> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAI2> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAI3> = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAW1 where T: Iterator = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAW2 where T: Iterator = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TAW3 where T: Iterator = T; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +existential type ETAI1>: Copy; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI2>: Copy; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI3>: Copy; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI4: Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI5: Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +existential type ETAI6: Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +trait TRI1> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRI2> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRI3> {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRS1: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRS2: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRS3: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRW1 where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRW2 where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRW3 where T: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRSW1 where Self: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRSW2 where Self: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRSW3 where Self: Iterator {} +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRA1 { type A: Iterator; } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRA2 { type A: Iterator; } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +trait TRA3 { type A: Iterator; } +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +type TADyn1 = dyn Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TADyn2 = Box>; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] +type TADyn3 = dyn Iterator; +//~^ the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified [E0719] + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr new file mode 100644 index 0000000000000..fbf02ddc7032f --- /dev/null +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -0,0 +1,627 @@ +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:12:36 + | +LL | struct SI1> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:14:36 + | +LL | struct SI2> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:16:39 + | +LL | struct SI3> { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:18:45 + | +LL | struct SW1 where T: Iterator { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:20:45 + | +LL | struct SW2 where T: Iterator { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:22:48 + | +LL | struct SW3 where T: Iterator { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:25:34 + | +LL | enum EI1> { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:27:34 + | +LL | enum EI2> { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:29:37 + | +LL | enum EI3> { V(T) } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:31:43 + | +LL | enum EW1 where T: Iterator { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:33:43 + | +LL | enum EW2 where T: Iterator { V(T) } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:35:46 + | +LL | enum EW3 where T: Iterator { V(T) } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:38:35 + | +LL | union UI1> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:40:35 + | +LL | union UI2> { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:42:38 + | +LL | union UI3> { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:44:44 + | +LL | union UW1 where T: Iterator { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:46:44 + | +LL | union UW2 where T: Iterator { f: T } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:48:47 + | +LL | union UW3 where T: Iterator { f: T } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:51:32 + | +LL | fn FI1>() {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:53:32 + | +LL | fn FI2>() {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:55:35 + | +LL | fn FI3>() {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:57:43 + | +LL | fn FW1() where T: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:59:43 + | +LL | fn FW2() where T: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:61:46 + | +LL | fn FW3() where T: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:70:40 + | +LL | fn FAPIT1(_: impl Iterator) {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:72:40 + | +LL | fn FAPIT2(_: impl Iterator) {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:74:43 + | +LL | fn FAPIT3(_: impl Iterator) {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:64:42 + | +LL | fn FRPIT1() -> impl Iterator { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:66:42 + | +LL | fn FRPIT2() -> impl Iterator { iter::empty() } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:68:45 + | +LL | fn FRPIT3() -> impl Iterator { iter::empty() } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:77:39 + | +LL | const CIT1: impl Iterator = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:79:39 + | +LL | const CIT2: impl Iterator = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:81:42 + | +LL | const CIT3: impl Iterator = iter::empty(); + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:83:40 + | +LL | static SIT1: impl Iterator = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:85:40 + | +LL | static SIT2: impl Iterator = iter::empty(); + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:87:43 + | +LL | static SIT3: impl Iterator = iter::empty(); + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:90:46 + | +LL | fn lit1() { let _: impl Iterator = iter::empty(); } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:92:46 + | +LL | fn lit2() { let _: impl Iterator = iter::empty(); } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:94:49 + | +LL | fn lit3() { let _: impl Iterator = iter::empty(); } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:97:35 + | +LL | type TAI1> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:99:35 + | +LL | type TAI2> = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:101:38 + | +LL | type TAI3> = T; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:103:44 + | +LL | type TAW1 where T: Iterator = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:105:44 + | +LL | type TAW2 where T: Iterator = T; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:107:47 + | +LL | type TAW3 where T: Iterator = T; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:110:1 + | +LL | existential type ETAI1>: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:110:48 + | +LL | existential type ETAI1>: Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:112:1 + | +LL | existential type ETAI2>: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:112:48 + | +LL | existential type ETAI2>: Copy; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:114:1 + | +LL | existential type ETAI3>: Copy; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:114:51 + | +LL | existential type ETAI3>: Copy; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:116:1 + | +LL | existential type ETAI4: Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:116:46 + | +LL | existential type ETAI4: Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:118:1 + | +LL | existential type ETAI5: Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:118:46 + | +LL | existential type ETAI5: Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + --> $DIR/duplicate.rs:120:1 + | +LL | existential type ETAI6: Iterator; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:120:49 + | +LL | existential type ETAI6: Iterator; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:123:36 + | +LL | trait TRI1> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:125:36 + | +LL | trait TRI2> {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:127:39 + | +LL | trait TRI3> {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:129:34 + | +LL | trait TRS1: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:131:34 + | +LL | trait TRS2: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:133:37 + | +LL | trait TRS3: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:135:45 + | +LL | trait TRW1 where T: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:137:45 + | +LL | trait TRW2 where T: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:139:48 + | +LL | trait TRW3 where T: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:141:46 + | +LL | trait TRSW1 where Self: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:143:46 + | +LL | trait TRSW2 where Self: Iterator {} + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:145:49 + | +LL | trait TRSW3 where Self: Iterator {} + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:147:43 + | +LL | trait TRA1 { type A: Iterator; } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:149:43 + | +LL | trait TRA2 { type A: Iterator; } + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:151:46 + | +LL | trait TRA3 { type A: Iterator; } + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:154:40 + | +LL | type TADyn1 = dyn Iterator; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:156:44 + | +LL | type TADyn2 = Box>; + | ---------- ^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified + --> $DIR/duplicate.rs:158:43 + | +LL | type TADyn3 = dyn Iterator; + | ------------- ^^^^^^^^^^^^^ re-bound here + | | + | `Item` bound here first + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: aborting due to 93 previous errors + +For more information about this error, try `rustc --explain E0719`. diff --git a/src/test/ui/associated-type-bounds/dyn-existential-type.rs b/src/test/ui/associated-type-bounds/dyn-existential-type.rs new file mode 100644 index 0000000000000..dc0afaa934a9e --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-existential-type.rs @@ -0,0 +1,67 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(existential_type)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +type Et1 = Box>; +fn def_et1() -> Et1 { Box::new(S1) } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +type Et2 = Box>; +fn def_et2() -> Et2 { Box::new(S1) } +pub fn use_et2() { assert_static(def_et2().mk()); } + +type Et3 = Box>>>>; +fn def_et3() -> Et3 { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + Box::new(A) +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +type Et4 = Box Tr2<'a>>>; +fn def_et4() -> Et4 { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + Box::new(A) +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.rs b/src/test/ui/associated-type-bounds/dyn-lcsit.rs new file mode 100644 index 0000000000000..439304fd309c8 --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-lcsit.rs @@ -0,0 +1,69 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(impl_trait_in_bindings)] + +#![allow(non_upper_case_globals)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +#[derive(Copy, Clone)] +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +const cdef_et1: &dyn Tr1 = &S1; +const sdef_et1: &dyn Tr1 = &S1; +pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); } + +const cdef_et2: &(dyn Tr1 + Sync) = &S1; +static sdef_et2: &(dyn Tr1 + Sync) = &S1; +pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); } + +const cdef_et3: &dyn Tr1>>> = { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + &A +}; +pub fn use_et3() { + let _0 = cdef_et3.mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +const cdef_et4: &(dyn Tr1 Tr2<'a>> + Sync) = { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + &A +}; +static sdef_et4: &(dyn Tr1 Tr2<'a>> + Sync) = cdef_et4; +pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs b/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs new file mode 100644 index 0000000000000..f22a6c44cb84d --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-rpit-and-let.rs @@ -0,0 +1,73 @@ +// run-pass + +// FIXME: uncomment let binding types below when `impl_trait_in_bindings` feature is fixed. + +#![feature(associated_type_bounds)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +fn def_et1() -> Box> { + let x /* : Box> */ = Box::new(S1); + x +} +pub fn use_et1() { assert_copy(def_et1().mk()); } + +fn def_et2() -> Box> { + let x /* : Box> */ = Box::new(S1); + x +} +pub fn use_et2() { assert_static(def_et2().mk()); } + +fn def_et3() -> Box>>>> { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + let x /* : Box>>>> */ + = Box::new(A); + x +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +fn def_et4() -> Box Tr2<'a>>> { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + let x /* : Box Tr2<'a>>> */ = Box::new(A); + x +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs new file mode 100644 index 0000000000000..1b3e978594d69 --- /dev/null +++ b/src/test/ui/associated-type-bounds/entails-sized-object-safety.rs @@ -0,0 +1,26 @@ +// compile-pass + +#![feature(associated_type_bounds)] + +trait Tr1: Sized { type As1; } +trait Tr2<'a>: Sized { type As2; } + +trait ObjTr1 { fn foo() -> Self where Self: Tr1; } +fn _assert_obj_safe_1(_: Box) {} + +trait ObjTr2 { fn foo() -> Self where Self: Tr1; } +fn _assert_obj_safe_2(_: Box) {} + +trait ObjTr3 { fn foo() -> Self where Self: Tr1 + 'static + Copy>; } +fn _assert_obj_safe_3(_: Box) {} + +trait ObjTr4 { fn foo() -> Self where Self: Tr1 Tr2<'a>>; } +fn _assert_obj_safe_4(_: Box) {} + +trait ObjTr5 { fn foo() -> Self where for<'a> Self: Tr1>; } +fn _assert_obj_safe_5(_: Box) {} + +trait ObjTr6 { fn foo() -> Self where Self: for<'a> Tr1 Tr2<'b>>>; } +fn _assert_obj_safe_6(_: Box) {} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/enum-bounds.rs b/src/test/ui/associated-type-bounds/enum-bounds.rs new file mode 100644 index 0000000000000..a6b0bb7070b7a --- /dev/null +++ b/src/test/ui/associated-type-bounds/enum-bounds.rs @@ -0,0 +1,122 @@ +// run-pass + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 { type As3; } +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 { type As3 = fn() -> u8; } +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +enum En1> { + Outest(T), + Outer(T::As1), + Inner(::As2), +} + +fn wrap_en1_1(x: T) -> En1 where T: Tr1, T::As1: Tr2 { + En1::Outest(x) +} + +fn wrap_en1_2(x: T::As1) -> En1 where T: Tr1, T::As1: Tr2 { + En1::Outer(x) +} + +fn wrap_en1_3(x: ::As2) -> En1 where T: Tr1, T::As1: Tr2 { + En1::Inner(x) +} + +enum En2>> { + V0(T), + V1(T::As1), + V2(::As2), + V3(<::As2 as Tr3>::As3), +} + +enum En3> { + V0(T), + V1(&'static T::As1), +} + +enum En4<'x1, 'x2, T: Tr1 Tr4<'l>>> { + V0(&'x1 >::As4), + V1(&'x2 >::As4), +} + +enum _En5<'x1, 'x2, T: Tr1 Tr4<'l, As4: Copy>>> { + _V0(&'x1 >::As4), + _V1(&'x2 >::As4), +} + +enum En6 +where + T: Tr1, +{ + V0(T), + V1(::As2), + V2(&'static T::As1), + V3(::As5), +} + +enum _En7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, +{ + V0(&'a T), + V1(&'b ::As2), +} + +fn _make_en7<'a, 'b, T>(x: _En7<'a, 'b, T>) +where + T: Tr1, +{ + match x { + _En7::V0(x) => { + let _: &'a T = &x; + }, + _En7::V1(_) => {}, + } +} + +enum EnSelf where Self: Tr1 { + V0(T), + V1(::As1), + V2(<::As1 as Tr2>::As2), +} + +impl Tr1 for EnSelf<&'static str> { type As1 = bool; } + +fn main() { + if let En1::Outest("foo") = wrap_en1_1::<_>("foo") {} else { panic!() }; + if let En1::Outer(true) = wrap_en1_2::<&str>(true) {} else { panic!() }; + if let En1::Inner(24u8) = wrap_en1_3::<&str>(24u8) {} else { panic!() }; + + let _ = En2::<_>::V0("151571"); + let _ = En2::<&str>::V1(false); + let _ = En2::<&str>::V2(42u8); + let _ = En2::<&str>::V3(|| 12u8); + + let _ = En3::<_>::V0("deadbeef"); + let _ = En3::<&str>::V1(&true); + + let f1 = (1,); + let f2 = (2,); + let _ = En4::<()>::V0(&f1.0); + let _ = En4::<()>::V1(&f2.0); + + let _ = En6::<_>::V0("bar"); + let _ = En6::<&str>::V1(24u8); + let _ = En6::<&str>::V2(&false); + let _ = En6::<&str>::V3(12u16); + + let _ = EnSelf::<_>::V0("foo"); + let _ = EnSelf::<&'static str>::V1(true); + let _ = EnSelf::<&'static str>::V2(24u8); +} diff --git a/src/test/ui/associated-type-bounds/existential-type.rs b/src/test/ui/associated-type-bounds/existential-type.rs new file mode 100644 index 0000000000000..87046aec5c4ab --- /dev/null +++ b/src/test/ui/associated-type-bounds/existential-type.rs @@ -0,0 +1,67 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(existential_type)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(self) -> Self::As1 { S2 } } + +existential type Et1: Tr1; +fn def_et1() -> Et1 { S1 } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +existential type Et2: Tr1; +fn def_et2() -> Et2 { S1 } +pub fn use_et2() { assert_static(def_et2().mk()); } + +existential type Et3: Tr1>>>; +fn def_et3() -> Et3 { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(self) -> Self::As1 { 0..10 } + }; + A +} +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +existential type Et4: Tr1 Tr2<'a>>; +fn def_et4() -> Et4 { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + A +} +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/fn-apit.rs b/src/test/ui/associated-type-bounds/fn-apit.rs new file mode 100644 index 0000000000000..7e208b4e70d81 --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-apit.rs @@ -0,0 +1,58 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +fn apit_bound(beta: impl Beta) -> usize { + desugared_bound(beta) +} + +fn apit_bound_region(beta: impl Beta) -> usize { + desugared_bound_region(beta) +} + +fn apit_bound_multi( + beta: impl Copy + Beta +) -> usize { + desugared_bound_multi(beta) +} + +fn apit_bound_region_forall( + beta: impl Beta Epsilon<'a>> +) -> usize { + desugared_bound_region_forall(beta) +} + +fn apit_bound_region_forall2( + beta: impl Beta Epsilon<'a, Zeta: Eta>> +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn apit_bound_nested( + beta: impl Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn apit_bound_nested2( + beta: impl Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, apit_bound(beta)); + assert_eq!(24, apit_bound_region(beta)); + assert_eq!(42 + 24 + 1337, apit_bound_multi(beta)); + assert_eq!(7331 * 2, apit_bound_region_forall(beta)); + assert_eq!(42 + 1337, apit_bound_nested(beta)); + assert_eq!(42 + 1337, apit_bound_nested2(beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-aux.rs b/src/test/ui/associated-type-bounds/fn-aux.rs new file mode 100644 index 0000000000000..434bdbe996c63 --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-aux.rs @@ -0,0 +1,12 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +fn main() { + desugared(); +} diff --git a/src/test/ui/associated-type-bounds/fn-dyn-apit.rs b/src/test/ui/associated-type-bounds/fn-dyn-apit.rs new file mode 100644 index 0000000000000..9ff4a50e1e6e4 --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-dyn-apit.rs @@ -0,0 +1,60 @@ +// run-pass +// aux-build:fn-dyn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_dyn_aux; + +use fn_dyn_aux::*; + +// ATB, APIT (dyn trait): + +fn dyn_apit_bound(beta: &dyn Beta) -> usize { + desugared_bound(beta) +} + +fn dyn_apit_bound_region(beta: &dyn Beta) -> usize { + desugared_bound_region(beta) +} + +fn dyn_apit_bound_multi( + beta: &(dyn Beta + Send) +) -> usize { + desugared_bound_multi(beta) +} + +fn dyn_apit_bound_region_forall( + beta: &dyn Beta Epsilon<'a>> +) -> usize { + desugared_bound_region_forall(beta) +} + +fn dyn_apit_bound_region_forall2( + beta: &dyn Beta Epsilon<'a, Zeta: Eta>> +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn dyn_apit_bound_nested( + beta: &dyn Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn dyn_apit_bound_nested2( + beta: &dyn Beta> +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, dyn_apit_bound(&beta)); + assert_eq!(24, dyn_apit_bound_region(&beta)); + assert_eq!(42 + 24 + 1337, dyn_apit_bound_multi(&beta)); + assert_eq!(7331 * 2, dyn_apit_bound_region_forall(&beta)); + assert_eq!(42 + 1337, dyn_apit_bound_nested(&beta)); + assert_eq!(42 + 1337, dyn_apit_bound_nested2(&beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-inline.rs b/src/test/ui/associated-type-bounds/fn-inline.rs new file mode 100644 index 0000000000000..7b188763b7a5e --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-inline.rs @@ -0,0 +1,62 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, Type parameters, Inline bounds: + +fn inline_bound>(beta: B) -> usize { + desugared_bound(beta) +} + +fn inline_bound_region>(beta: B) -> usize { + desugared_bound_region(beta) +} + +fn inline_bound_multi>( + beta: B +) -> usize { + desugared_bound_multi(beta) +} + +fn inline_bound_region_specific<'a, B: Beta>>( + gamma: &'a B::Gamma +) -> usize { + desugared_bound_region_specific::(gamma) +} + +fn inline_bound_region_forall Epsilon<'a>>>( + beta: B +) -> usize { + desugared_bound_region_forall(beta) +} + +fn inline_bound_region_forall2 Epsilon<'a, Zeta: Eta>>>( + beta: B +) -> usize { + desugared_bound_region_forall2(beta) +} + +fn inline_bound_nested>>( + beta: B +) -> usize { + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, inline_bound(beta)); + assert_eq!(24, inline_bound_region(beta)); + assert_eq!(42 + 24 + 1337, inline_bound_multi(beta)); + assert_eq!(7331, inline_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, inline_bound_region_forall(beta)); + // FIXME: requires lazy normalization. + // assert_eq!(7331 * 2, inline_bound_region_forall2(beta)); + assert_eq!(42 + 1337, inline_bound_nested(beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-where.rs b/src/test/ui/associated-type-bounds/fn-where.rs new file mode 100644 index 0000000000000..60d7149a56f25 --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-where.rs @@ -0,0 +1,78 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, Type parameters, Where-clauses: + +fn where_bound(beta: B) -> usize +where + B: Beta +{ + desugared_bound(beta) +} + +fn where_bound_region(beta: B) -> usize +where + B: Beta +{ + desugared_bound_region(beta) +} + +fn where_bound_multi(beta: B) -> usize +where + B: Copy + Beta, +{ + desugared_bound_multi(beta) +} + +fn where_bound_region_specific<'a, B>(gamma: &'a B::Gamma) -> usize +where + B: Beta>, +{ + desugared_bound_region_specific::(gamma) +} + +fn where_bound_region_forall(beta: B) -> usize +where + B: Beta Epsilon<'a>>, +{ + desugared_bound_region_forall(beta) +} + +fn where_bound_region_forall2(beta: B) -> usize +where + B: Beta Epsilon<'a, Zeta: Eta>>, +{ + desugared_bound_region_forall2(beta) +} + +fn where_contraint_region_forall(beta: B) -> usize +where + for<'a> &'a B: Beta, +{ + desugared_contraint_region_forall(beta) +} + +fn where_bound_nested(beta: B) -> usize +where + B: Beta>, +{ + desugared_bound_nested(beta) +} + +fn main() { + let beta = BetaType; + let gamma = beta.gamma(); + + assert_eq!(42, where_bound(beta)); + assert_eq!(24, where_bound_region(beta)); + assert_eq!(42 + 24 + 1337, where_bound_multi(beta)); + assert_eq!(7331, where_bound_region_specific::(&gamma)); + assert_eq!(7331 * 2, where_bound_region_forall::(beta)); + assert_eq!(42 + 1337, where_bound_nested::(beta)); +} diff --git a/src/test/ui/associated-type-bounds/fn-wrap-apit.rs b/src/test/ui/associated-type-bounds/fn-wrap-apit.rs new file mode 100644 index 0000000000000..23790d416e1f7 --- /dev/null +++ b/src/test/ui/associated-type-bounds/fn-wrap-apit.rs @@ -0,0 +1,64 @@ +// run-pass +// aux-build:fn-aux.rs + +#![feature(associated_type_bounds)] + +extern crate fn_aux; + +use fn_aux::*; + +// ATB, APIT + Wrap: + +struct Wrap(T); + +fn wrap_apit_bound(beta: Wrap>) -> usize { + desugared_bound(beta.0) +} + +fn wrap_apit_bound_region(beta: Wrap>) -> usize { + desugared_bound_region(beta.0) +} + +fn wrap_apit_bound_multi( + beta: Wrap> +) -> usize { + desugared_bound_multi(beta.0) +} + +fn wrap_apit_bound_region_forall( + beta: Wrap Epsilon<'a>>> +) -> usize { + desugared_bound_region_forall(beta.0) +} + +fn wrap_apit_bound_region_forall2( + beta: Wrap Epsilon<'a, Zeta: Eta>>> +) -> usize { + desugared_bound_region_forall2(beta.0) +} + +fn wrap_apit_bound_nested( + beta: Wrap>> +) -> usize { + desugared_bound_nested(beta.0) +} + +fn wrap_apit_bound_nested2( + beta: Wrap>> +) -> usize { + desugared_bound_nested(beta.0) +} + +fn main() { + let beta = BetaType; + let _gamma = beta.gamma(); + + assert_eq!(42, wrap_apit_bound(Wrap(beta))); + assert_eq!(24, wrap_apit_bound_region(Wrap(beta))); + assert_eq!(42 + 24 + 1337, wrap_apit_bound_multi(Wrap(beta))); + assert_eq!(7331 * 2, wrap_apit_bound_region_forall(Wrap(beta))); + // FIXME: requires lazy normalization. + // assert_eq!(7331 * 2, wrap_apit_bound_region_forall2(Wrap(beta))); + assert_eq!(42 + 1337, wrap_apit_bound_nested(Wrap(beta))); + assert_eq!(42 + 1337, wrap_apit_bound_nested2(Wrap(beta))); +} diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.rs b/src/test/ui/associated-type-bounds/implied-region-constraints.rs new file mode 100644 index 0000000000000..4dbaab50a61db --- /dev/null +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.rs @@ -0,0 +1,47 @@ +// compile-fail + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } + +struct St<'a, 'b, T: Tr1> { // `T: 'b` is *not* implied! + f0: &'a T, // `T: 'a` is implied. + f1: &'b ::As2, // `::As2: 'a` is implied. +} + +fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + // This should fail because `T: 'b` is not implied from `WF(St<'a, 'b, T>)`. + let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; + //~^ ERROR lifetime mismatch [E0623] +} + +enum En7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, + T::As1: Tr2, +{ + V0(&'a T), + V1(&'b ::As2), +} + +fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + match x { + En7::V0(x) => { + // Also fails for the same reason as above: + let _failure_proves_not_implied_outlives_region_b: &'b T = &x; + //~^ ERROR lifetime mismatch [E0623] + }, + En7::V1(_) => {}, + } +} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr new file mode 100644 index 0000000000000..b07b20272a8c0 --- /dev/null +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr @@ -0,0 +1,25 @@ +error[E0623]: lifetime mismatch + --> $DIR/implied-region-constraints.rs:19:64 + | +LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) + | ------------- + | | + | this type is declared with multiple lifetimes... +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; + | ^^^^^ ...but data with one lifetime flows into the other here + +error[E0623]: lifetime mismatch + --> $DIR/implied-region-constraints.rs:40:72 + | +LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) + | -------------- + | | + | this type is declared with multiple lifetimes... +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x; + | ^^ ...but data with one lifetime flows into the other here + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/associated-type-bounds/inside-adt.rs b/src/test/ui/associated-type-bounds/inside-adt.rs new file mode 100644 index 0000000000000..1257dc6e94b39 --- /dev/null +++ b/src/test/ui/associated-type-bounds/inside-adt.rs @@ -0,0 +1,36 @@ +// compile-fail +// ignore-tidy-linelength +// error-pattern:could not find defining uses + +#![feature(associated_type_bounds)] +#![feature(untagged_unions)] + +struct S1 { f: dyn Iterator } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +struct S2 { f: Box> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +struct S3 { f: dyn Iterator } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] + +enum E1 { V(dyn Iterator) } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +enum E2 { V(Box>) } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +enum E3 { V(dyn Iterator) } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] + +union U1 { f: dyn Iterator } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +union U2 { f: Box> } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] +union U3 { f: dyn Iterator } +//~^ associated type bounds are not allowed within structs, enums, or unions +//~| the value of the associated type `Item` (from the trait `std::iter::Iterator`) must be specified [E0191] diff --git a/src/test/ui/associated-type-bounds/inside-adt.stderr b/src/test/ui/associated-type-bounds/inside-adt.stderr new file mode 100644 index 0000000000000..7bdd71b8296ff --- /dev/null +++ b/src/test/ui/associated-type-bounds/inside-adt.stderr @@ -0,0 +1,79 @@ +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:8:29 + | +LL | struct S1 { f: dyn Iterator } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:11:33 + | +LL | struct S2 { f: Box> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:14:29 + | +LL | struct S3 { f: dyn Iterator } + | ^^^^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:18:26 + | +LL | enum E1 { V(dyn Iterator) } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:21:30 + | +LL | enum E2 { V(Box>) } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:24:26 + | +LL | enum E3 { V(dyn Iterator) } + | ^^^^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:28:28 + | +LL | union U1 { f: dyn Iterator } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:31:32 + | +LL | union U2 { f: Box> } + | ^^^^^^^^^^ + +error: associated type bounds are not allowed within structs, enums, or unions + --> $DIR/inside-adt.rs:34:28 + | +LL | union U3 { f: dyn Iterator } + | ^^^^^^^^^^^^^ + +error[E0601]: `main` function not found in crate `inside_adt` + | + = note: consider adding a `main` function to `$DIR/inside-adt.rs` + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: could not find defining uses + +error: aborting due to 19 previous errors + +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/associated-type-bounds/lcsit.rs b/src/test/ui/associated-type-bounds/lcsit.rs new file mode 100644 index 0000000000000..85b6e804b4ef6 --- /dev/null +++ b/src/test/ui/associated-type-bounds/lcsit.rs @@ -0,0 +1,78 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(impl_trait_in_bindings)] + +#![allow(non_upper_case_globals)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(&self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +#[derive(Copy, Clone)] +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(&self) -> Self::As1 { S2 } } + +const cdef_et1: impl Copy + Tr1 = { + let x: impl Copy + Tr1 = S1; + x +}; +static sdef_et1: impl Copy + Tr1 = cdef_et1; +pub fn use_et1() { assert_copy(cdef_et1.mk()); assert_copy(sdef_et1.mk()); } + +const cdef_et2: impl Tr1 = { + let x: impl Tr1 = S1; + x +}; +static sdef_et2: impl Tr1 = cdef_et2; +pub fn use_et2() { assert_static(cdef_et2.mk()); assert_static(sdef_et2.mk()); } + +const cdef_et3: impl Tr1>>> = { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(&self) -> Self::As1 { 0..10 } + }; + let x: impl Tr1>>> = A; + x +}; +pub fn use_et3() { + let _0 = cdef_et3.mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +const cdef_et4: impl Copy + Tr1 Tr2<'a>> = { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(&self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + let x: impl Copy + Tr1 Tr2<'a>> = A; + x +}; + +static sdef_et4: impl Copy + Tr1 Tr2<'a>> = cdef_et4; +pub fn use_et4() { assert_forall_tr2(cdef_et4.mk()); assert_forall_tr2(sdef_et4.mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs new file mode 100644 index 0000000000000..25c2c2916f3bc --- /dev/null +++ b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs @@ -0,0 +1,25 @@ +// compile-fail + +#![feature(associated_type_bounds)] + +use std::fmt::Debug; + +trait Lam { type App; } + +fn nested_bounds<_0, _1, _2, D>() +where + D: Clone + Iterator Iterator Lam<&'a &'b u8, App = _0>>>, + //~^ ERROR nested quantification of lifetimes [E0316] + _0: Debug, +{} + +fn nested_bounds_desugared<_0, _1, _2, D>() +where + D: Clone + Iterator, + _2: Send + for<'a> Iterator, + for<'a> <_2 as Iterator>::Item: for<'b> Lam<&'a &'b u8, App = _0>, + //~^ ERROR nested quantification of lifetimes [E0316] + _0: Debug, +{} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr new file mode 100644 index 0000000000000..44fa9e89d3502 --- /dev/null +++ b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr @@ -0,0 +1,9 @@ +error[E0316]: nested quantification of lifetimes + --> $DIR/nested-lifetime-bounds.rs:20:37 + | +LL | for<'a> <_2 as Iterator>::Item: for<'b> Lam<&'a &'b u8, App = _0>, + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0316`. diff --git a/src/test/ui/associated-type-bounds/rpit.rs b/src/test/ui/associated-type-bounds/rpit.rs new file mode 100644 index 0000000000000..7b640d5a457df --- /dev/null +++ b/src/test/ui/associated-type-bounds/rpit.rs @@ -0,0 +1,64 @@ +// run-pass + +#![feature(associated_type_bounds)] + +use std::ops::Add; + +trait Tr1 { type As1; fn mk(self) -> Self::As1; } +trait Tr2<'a> { fn tr2(self) -> &'a Self; } + +fn assert_copy(x: T) { let _x = x; let _x = x; } +fn assert_static(_: T) {} +fn assert_forall_tr2 Tr2<'a>>(_: T) {} + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; fn mk(self) -> Self::As1 { S2 } } + +fn def_et1() -> impl Tr1 { S1 } +pub fn use_et1() { assert_copy(def_et1().mk()); } + +fn def_et2() -> impl Tr1 { S1 } +pub fn use_et2() { assert_static(def_et2().mk()); } + +fn def_et3() -> impl Tr1>>> { + struct A; + impl Tr1 for A { + type As1 = core::ops::Range; + fn mk(self) -> Self::As1 { 0..10 } + }; + A +} + +pub fn use_et3() { + let _0 = def_et3().mk().clone(); + let mut s = 0u8; + for _1 in _0 { + let _2 = _1 + 1u8; + s += _2.into(); + } + assert_eq!(s, (0..10).map(|x| x + 1).sum()); +} + +fn def_et4() -> impl Tr1 Tr2<'a>> { + #[derive(Copy, Clone)] + struct A; + impl Tr1 for A { + type As1 = A; + fn mk(self) -> A { A } + } + impl<'a> Tr2<'a> for A { + fn tr2(self) -> &'a Self { &A } + } + A +} + +pub fn use_et4() { assert_forall_tr2(def_et4().mk()); } + +fn main() { + let _ = use_et1(); + let _ = use_et2(); + let _ = use_et3(); + let _ = use_et4(); +} diff --git a/src/test/ui/associated-type-bounds/struct-bounds.rs b/src/test/ui/associated-type-bounds/struct-bounds.rs new file mode 100644 index 0000000000000..2d189cd66724a --- /dev/null +++ b/src/test/ui/associated-type-bounds/struct-bounds.rs @@ -0,0 +1,115 @@ +// run-pass + +#![feature(associated_type_bounds)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 {} +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 {} +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +struct St1> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +fn unwrap_1_st1>(x: St1) -> (T, T::As1, ::As2) { + (x.outest, x.outer, x.inner) +} + +fn unwrap_2_st1(x: St1) -> (T, T::As1, ::As2) +where + T: Tr1, + T::As1: Tr2, +{ + unwrap_1_st1(x) +} + +struct St2>> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +struct St3> { + outest: T, + outer: &'static T::As1, +} + +struct St4<'x1, 'x2, T: Tr1 Tr4<'l>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +struct St5<'x1, 'x2, T: Tr1 Tr4<'l, As4: Copy>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +struct St6 +where + T: Tr1, +{ + f0: T, + f1: ::As2, + f2: &'static T::As1, + f3: ::As5, +} + +struct St7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, +{ + f0: &'a T, + f1: &'b ::As2, +} + +fn _use_st7<'a, 'b, T>(x: St7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + let _: &'a T = &x.f0; +} + +struct StSelf where Self: Tr1 { + f2: <::As1 as Tr2>::As2, +} + +impl Tr1 for StSelf<&'static str> { type As1 = bool; } + +fn main() { + let st1 = St1 { outest: "foo", outer: true, inner: 42u8 }; + assert_eq!(("foo", true, 42), unwrap_1_st1(st1)); + + let _ = St2 { outest: "foo", outer: true, inner: 42u8 }; + + let _ = St3 { outest: "foo", outer: &true }; + + let f1 = (1,); + let f2 = (2,); + let st4 = St4::<()> { f1: &f1.0, f2: &f2.0, }; + assert_eq!((&1, &2), (st4.f1, st4.f2)); + + // FIXME: requires lazy normalization. + /* + let f1 = (1,); + let f2 = (2,); + let st5 = St5::<()> { f1: &f1.0, f2: &f2.0, }; + assert_eq!((&1, &2), (st5.f1, st5.f2)); + */ + + let st6 = St6 { f0: "bar", f1: 24u8, f2: &true, f3: 12u16, }; + assert_eq!(("bar", 24, &true, 12), (st6.f0, st6.f1, st6.f2, st6.f3)); + + let stself = StSelf::<&'static str> { f2: 42u8 }; + assert_eq!(stself.f2, 42u8); +} diff --git a/src/test/ui/associated-type-bounds/trait-params.rs b/src/test/ui/associated-type-bounds/trait-params.rs new file mode 100644 index 0000000000000..a9081d50cfc5d --- /dev/null +++ b/src/test/ui/associated-type-bounds/trait-params.rs @@ -0,0 +1,116 @@ +// compile-pass + +#![feature(associated_type_bounds)] + +use std::iter::Once; +use std::ops::Range; + +pub trait Three { type A; type B; type C; } +pub fn assert_three() {} +pub fn assert_iterator() {} +pub fn assert_copy() {} +pub fn assert_static() {} +pub fn assert_send() {} +pub fn assert_forall_into Into<&'a u8>>() {} + +struct A; struct B; +impl<'a> Into<&'a u8> for A { fn into(self) -> &'a u8 { &0 } } +impl Three for B { type A = Range; type B = Range; type C = Range; } + +trait Case1 +where + A: Iterator, + B: Iterator, + C: Iterator, + D: Iterator Into<&'a u8>>, + E: Three, B: Iterator, C: Iterator>, + Self: Three, +{ + fn _a() { + assert_iterator::(); + assert_copy::(); + } + fn _b() { + assert_iterator::(); + assert_static::(); + } + fn _c() { + assert_iterator::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } + fn _d() { + assert_iterator::(); + assert_forall_into::(); + } + fn _e() { + assert_three::(); + assert_iterator::(); + assert_iterator::(); + assert_iterator::(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + } + fn _self() { + assert_three::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } +} + +struct DataCase1; +impl Three for DataCase1 { type A = u8; type B = u8; type C = u8; } +impl Case1, Range, Range, Once, B> for DataCase1 {} + +trait Case2< + A: Iterator, + B: Iterator, + C: Iterator, + D: Iterator Into<&'a u8>>, + E: Three, B: Iterator, C: Iterator>, +>: + Three +{ + fn _a() { + assert_iterator::(); + assert_copy::(); + } + fn _b() { + assert_iterator::(); + assert_static::(); + } + fn _c() { + assert_iterator::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } + fn _d() { + assert_iterator::(); + assert_forall_into::(); + } + fn _e() { + assert_three::(); + assert_iterator::(); + assert_iterator::(); + assert_iterator::(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + assert_copy::<::Item>(); + } + fn _self() { + assert_three::(); + assert_copy::(); + assert_static::(); + assert_send::(); + } +} + +struct DataCase2; +impl Three for DataCase2 { type A = u8; type B = u8; type C = u8; } +impl Case2, Range, Range, Once, B> for DataCase2 {} + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/type-alias.rs b/src/test/ui/associated-type-bounds/type-alias.rs new file mode 100644 index 0000000000000..1602fdd275a2e --- /dev/null +++ b/src/test/ui/associated-type-bounds/type-alias.rs @@ -0,0 +1,19 @@ +// compile-pass + +#![feature(associated_type_bounds)] + +type _TaWhere1 where T: Iterator = T; +type _TaWhere2 where T: Iterator = T; +type _TaWhere3 where T: Iterator = T; +type _TaWhere4 where T: Iterator = T; +type _TaWhere5 where T: Iterator Into<&'a u8>> = T; +type _TaWhere6 where T: Iterator> = T; + +type _TaInline1> = T; +type _TaInline2> = T; +type _TaInline3> = T; +type _TaInline4> = T; +type _TaInline5 Into<&'a u8>>> = T; +type _TaInline6>> = T; + +fn main() {} diff --git a/src/test/ui/associated-type-bounds/type-alias.stderr b/src/test/ui/associated-type-bounds/type-alias.stderr new file mode 100644 index 0000000000000..b93fc393ae32c --- /dev/null +++ b/src/test/ui/associated-type-bounds/type-alias.stderr @@ -0,0 +1,97 @@ +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:5:25 + | +LL | type _TaWhere1 where T: Iterator = T; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: #[warn(type_alias_bounds)] on by default + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:6:25 + | +LL | type _TaWhere2 where T: Iterator = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:7:25 + | +LL | type _TaWhere3 where T: Iterator = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:8:25 + | +LL | type _TaWhere4 where T: Iterator = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:9:25 + | +LL | type _TaWhere5 where T: Iterator Into<&'a u8>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: where clauses are not enforced in type aliases + --> $DIR/type-alias.rs:10:25 + | +LL | type _TaWhere6 where T: Iterator> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the clause will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:12:20 + | +LL | type _TaInline1> = T; + | ^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:13:20 + | +LL | type _TaInline2> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:14:20 + | +LL | type _TaInline3> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:15:20 + | +LL | type _TaInline4> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:16:20 + | +LL | type _TaInline5 Into<&'a u8>>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + +warning: bounds on generic parameters are not enforced in type aliases + --> $DIR/type-alias.rs:17:20 + | +LL | type _TaInline6>> = T; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = help: the bound will not be checked when the type alias is used, and should be removed + diff --git a/src/test/ui/associated-type-bounds/union-bounds.rs b/src/test/ui/associated-type-bounds/union-bounds.rs new file mode 100644 index 0000000000000..ce482fff401c8 --- /dev/null +++ b/src/test/ui/associated-type-bounds/union-bounds.rs @@ -0,0 +1,123 @@ +// run-pass + +#![feature(associated_type_bounds)] +#![feature(untagged_unions)] + +#![allow(unions_with_drop_fields, unused_assignments)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } +trait Tr3 { type As3; } +trait Tr4<'a> { type As4; } +trait Tr5 { type As5; } + +impl Tr1 for &str { type As1 = bool; } +impl Tr2 for bool { type As2 = u8; } +impl Tr3 for u8 { type As3 = fn() -> u8; } +impl Tr1 for () { type As1 = (usize,); } +impl<'a> Tr4<'a> for (usize,) { type As4 = u8; } +impl Tr5 for bool { type As5 = u16; } + +union Un1> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +union Un2>> { + outest: T, + outer: T::As1, + inner: ::As2, +} + +union Un3> { + outest: T, + outer: &'static T::As1, +} + +union Un4<'x1, 'x2, T: Tr1 Tr4<'l>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +union _Un5<'x1, 'x2, T: Tr1 Tr4<'l, As4: Copy>>> { + f1: &'x1 >::As4, + f2: &'x2 >::As4, +} + +union Un6 +where + T: Tr1, +{ + f0: T, + f1: ::As2, + f2: &'static T::As1, + f3: ::As5, +} + +union _Un7<'a, 'b, T> // `::As2: 'a` is implied. +where + T: Tr1, +{ + f0: &'a T, + f1: &'b ::As2, +} + +unsafe fn _use_un7<'a, 'b, T>(x: _Un7<'a, 'b, T>) +where + T: Tr1, + T::As1: Tr2, +{ + let _: &'a T = &x.f0; +} + +union UnSelf where Self: Tr1 { + f0: T, + f1: ::As1, + f2: <::As1 as Tr2>::As2, +} + +impl Tr1 for UnSelf<&'static str> { type As1 = bool; } + +fn main() { + let mut un1 = Un1 { outest: "foo" }; + un1 = Un1 { outer: true }; + assert_eq!(unsafe { un1.outer }, true); + un1 = Un1 { inner: 42u8 }; + assert_eq!(unsafe { un1.inner }, 42u8); + + let mut un2 = Un2 { outest: "bar" }; + assert_eq!(unsafe { un2.outest }, "bar"); + un2 = Un2 { outer: true }; + assert_eq!(unsafe { un2.outer }, true); + un2 = Un2 { inner: 42u8 }; + assert_eq!(unsafe { un2.inner }, 42u8); + + let mut un3 = Un3 { outest: "baz" }; + assert_eq!(unsafe { un3.outest }, "baz"); + un3 = Un3 { outer: &true }; + assert_eq!(unsafe { *un3.outer }, true); + + let f1 = (1,); + let f2 = (2,); + let mut un4 = Un4::<()> { f1: &f1.0 }; + assert_eq!(1, unsafe { *un4.f1 }); + un4 = Un4 { f2: &f2.0 }; + assert_eq!(2, unsafe { *un4.f2 }); + + let mut un6 = Un6 { f0: "bar" }; + assert_eq!(unsafe { un6.f0 }, "bar"); + un6 = Un6 { f1: 24u8 }; + assert_eq!(unsafe { un6.f1 }, 24u8); + un6 = Un6 { f2: &true }; + assert_eq!(unsafe { un6.f2 }, &true); + un6 = Un6 { f3: 12u16 }; + assert_eq!(unsafe { un6.f3 }, 12u16); + + let mut unself = UnSelf::<_> { f0: "selfish" }; + assert_eq!(unsafe { unself.f0 }, "selfish"); + unself = UnSelf { f1: true }; + assert_eq!(unsafe { unself.f1 }, true); + unself = UnSelf { f2: 24u8 }; + assert_eq!(unsafe { unself.f2 }, 24u8); +} diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs new file mode 100644 index 0000000000000..6b4f5005d48f0 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs @@ -0,0 +1,71 @@ +#![feature(untagged_unions)] + +trait Tr1 { type As1; } +trait Tr2 { type As2; } + +struct S1; +#[derive(Copy, Clone)] +struct S2; +impl Tr1 for S1 { type As1 = S2; } + +trait _Tr3 { + type A: Iterator; + //~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + + type B: Iterator; + //~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +} + +struct _St1> { +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + outest: T, + outer: T::As1, + inner: ::As2, +} + +enum _En1> { +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + Outest(T), + Outer(T::As1), + Inner(::As2), +} + +union _Un1> { +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + outest: T, + outer: T::As1, + inner: ::As2, +} + +type _TaWhere1 where T: Iterator = T; +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + +fn _apit(_: impl Tr1) {} +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +fn _apit_dyn(_: &dyn Tr1) {} +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + +fn _rpit() -> impl Tr1 { S1 } +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +fn _rpit_dyn() -> Box> { Box::new(S1) } +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + +const _cdef: impl Tr1 = S1; +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] +// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. +// const _cdef_dyn: &dyn Tr1 = &S1; + +static _sdef: impl Tr1 = S1; +//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] +// FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. +// static _sdef_dyn: &dyn Tr1 = &S1; + +fn main() { + let _: impl Tr1 = S1; + //~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + //~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] + // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. + // let _: &dyn Tr1 = &S1; +} diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr new file mode 100644 index 0000000000000..9b83c1cfb33d1 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -0,0 +1,132 @@ +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:12:22 + | +LL | type A: Iterator; + | ^^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:15:22 + | +LL | type B: Iterator; + | ^^^^^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:19:20 + | +LL | struct _St1> { + | ^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:26:18 + | +LL | enum _En1> { + | ^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:33:19 + | +LL | union _Un1> { + | ^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:40:37 + | +LL | type _TaWhere1 where T: Iterator = T; + | ^^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:43:22 + | +LL | fn _apit(_: impl Tr1) {} + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:45:26 + | +LL | fn _apit_dyn(_: &dyn Tr1) {} + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:48:24 + | +LL | fn _rpit() -> impl Tr1 { S1 } + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:50:31 + | +LL | fn _rpit_dyn() -> Box> { Box::new(S1) } + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:53:23 + | +LL | const _cdef: impl Tr1 = S1; + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:59:24 + | +LL | static _sdef: impl Tr1 = S1; + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0658]: associated type bounds are unstable (see issue #52662) + --> $DIR/feature-gate-associated_type_bounds.rs:66:21 + | +LL | let _: impl Tr1 = S1; + | ^^^^^^^^^ + | + = help: add #![feature(associated_type_bounds)] to the crate attributes to enable + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/feature-gate-associated_type_bounds.rs:53:14 + | +LL | const _cdef: impl Tr1 = S1; + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/feature-gate-associated_type_bounds.rs:59:15 + | +LL | static _sdef: impl Tr1 = S1; + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + +error[E0562]: `impl Trait` not allowed outside of function and inherent method return types + --> $DIR/feature-gate-associated_type_bounds.rs:66:12 + | +LL | let _: impl Tr1 = S1; + | ^^^^^^^^^^^^^^^^^^^ + | + = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable + +error: aborting due to 16 previous errors + +Some errors occurred: E0562, E0658. +For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/ui/type/type-alias-bounds.stderr b/src/test/ui/type/type-alias-bounds.stderr index c0ff56d5ec038..177e5f893ed66 100644 --- a/src/test/ui/type/type-alias-bounds.stderr +++ b/src/test/ui/type/type-alias-bounds.stderr @@ -1,13 +1,3 @@ -warning: duplicate auto trait `::marker[0]::Send[0]` found in type parameter bounds - --> $DIR/type-alias-bounds.rs:8:14 - | -LL | type SVec = Vec; - | ^^^^ ^^^^ subsequent use of auto trait - | | - | first use of auto trait - | - = note: #[warn(duplicate_auto_traits_in_bounds)] on by default - warning: bounds on generic parameters are not enforced in type aliases --> $DIR/type-alias-bounds.rs:8:14 | From a71d55701e303514f936b862ae5cf0c410d2a785 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 4 May 2019 16:09:28 +0100 Subject: [PATCH 08/24] Addressed points raised in review. --- src/librustc/hir/lowering.rs | 15 +- src/librustc/hir/map/definitions.rs | 8 +- src/librustc/hir/map/mod.rs | 10 +- src/librustc/hir/mod.rs | 4 +- src/librustc/ich/impls_syntax.rs | 2 +- src/librustc/infer/opaque_types/mod.rs | 9 +- src/librustc_interface/util.rs | 21 +-- src/librustc_resolve/lib.rs | 2 +- src/librustc_typeck/astconv.rs | 6 +- src/librustc_typeck/collect.rs | 15 +- src/librustdoc/clean/mod.rs | 2 +- src/libsyntax_pos/hygiene.rs | 4 +- .../nested-lifetime-bounds.stderr | 1 - .../associated-types-path-2.stderr | 2 +- .../borrowck/borrowck-closures-two-mut.stderr | 104 ++++++++++-- src/test/ui/borrowck/borrowck-reinit.stderr | 16 +- .../ui/borrowck/borrowck-storage-dead.stderr | 12 +- src/test/ui/borrowck/immutable-arg.stderr | 14 +- src/test/ui/borrowck/issue-41962.stderr | 24 ++- .../const-param-before-other-params.stderr | 12 +- .../deprecation/deprecation-in-staged-api.rs | 4 +- .../feature-gate-associated_type_bounds.rs | 27 +-- ...feature-gate-associated_type_bounds.stderr | 55 +++--- .../yield-while-local-borrowed.stderr | 32 +++- src/test/ui/indexing-requires-a-uint.stderr | 2 +- .../integer-literal-suffix-inference.stderr | 36 ++-- src/test/ui/issues/issue-13359.stderr | 4 +- src/test/ui/issues/issue-31910.stderr | 2 +- src/test/ui/issues/issue-45697-1.stderr | 14 +- src/test/ui/issues/issue-45697.stderr | 14 +- src/test/ui/issues/issue-46471-1.stderr | 17 +- src/test/ui/issues/issue-46471.stderr | 20 ++- src/test/ui/issues/issue-46472.stderr | 24 ++- .../liveness-assign-imm-local-notes.stderr | 51 ++++-- ...od-ambig-one-trait-unknown-int-type.stderr | 2 +- .../ui/mismatched_types/issue-26480.stderr | 2 +- .../ui/moves/moves-based-on-type-tuple.stderr | 16 +- src/test/ui/nll/get_default.stderr | 58 +++++-- .../ui/nll/loan_ends_mid_block_pair.stderr | 60 ++++++- .../ui/nll/loan_ends_mid_block_vec.stderr | 88 +++++++++- .../nll/region-ends-after-if-condition.stderr | 32 +++- src/test/ui/nll/return_from_loop.stderr | 32 +++- src/test/ui/numeric/const-scope.stderr | 2 +- src/test/ui/numeric/len.stderr | 2 +- src/test/ui/numeric/numeric-cast-2.stderr | 6 +- src/test/ui/numeric/numeric-cast.stderr | 156 +++++++++--------- src/test/ui/pub/pub-restricted.stderr | 19 +-- src/test/ui/repeat_count.stderr | 4 +- src/test/ui/shift-various-bad-types.stderr | 2 +- src/test/ui/symbol-names/basic.stderr | 14 ++ src/test/ui/symbol-names/impl1.stderr | 26 +++ ...ounds-inconsistent-projection-error.stderr | 2 +- .../ui/tutorial-suffix-inference-test.stderr | 4 +- 53 files changed, 793 insertions(+), 319 deletions(-) create mode 100644 src/test/ui/symbol-names/basic.stderr create mode 100644 src/test/ui/symbol-names/impl1.stderr diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index eab01c0bf9924..a49744aa523a9 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1382,12 +1382,12 @@ impl<'a> LoweringContext<'a> { if existential_desugaring { // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. - let impl_ty_node_id = self.sess.next_node_id(); + let impl_trait_node_id = self.sess.next_node_id(); let parent_def_index = self.current_hir_id_owner.last().unwrap().0; self.resolver.definitions().create_def_with_parent( parent_def_index, - impl_ty_node_id, - DefPathData::Misc, + impl_trait_node_id, + DefPathData::ImplTrait, DefIndexAddressSpace::High, Mark::root(), DUMMY_SP @@ -1397,7 +1397,7 @@ impl<'a> LoweringContext<'a> { this.lower_ty( &Ty { id: this.sess.next_node_id(), - node: TyKind::ImplTrait(impl_ty_node_id, bounds.clone()), + node: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), span: DUMMY_SP, }, itctx, @@ -1410,9 +1410,8 @@ impl<'a> LoweringContext<'a> { let bounds = self.lower_param_bounds(bounds, itctx); let id = self.sess.next_node_id(); - let LoweredNodeId { node_id: _, hir_id } = self.lower_node_id(id); P(hir::Ty { - hir_id, + hir_id: self.lower_node_id(id), node: hir::TyKind::AssocTyExistential(bounds), span: DUMMY_SP, }) @@ -1423,7 +1422,7 @@ impl<'a> LoweringContext<'a> { hir::TypeBinding { hir_id: self.lower_node_id(c.id), ident: c.ident, - ty + ty, span: c.span, } } @@ -1647,7 +1646,7 @@ impl<'a> LoweringContext<'a> { // Not tracking it makes lints in rustc and clippy very fragile, as // frequently opened issues show. let exist_ty_span = self.mark_span_with_reason( - CompilerDesugaringKind::ExistentialReturnType, + CompilerDesugaringKind::ExistentialType, span, None, ); diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index b01eed8f6609d..3edd75fb725da 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -276,7 +276,7 @@ pub enum DefPathData { // they are treated specially by the `def_path` function. /// The crate root (marker) CrateRoot, - // Catch-all for random DefId things like DUMMY_NODE_ID + // Catch-all for random DefId things like `DUMMY_NODE_ID` Misc, // Different kinds of items and item-like things: /// An impl @@ -298,9 +298,9 @@ pub enum DefPathData { AnonConst, /// An `impl Trait` type node ImplTrait, - /// GlobalMetaData identifies a piece of crate metadata that is global to - /// a whole crate (as opposed to just one item). GlobalMetaData components - /// are only supposed to show up right below the crate root. + /// Identifies a piece of crate metadata that is global to a whole crate + /// (as opposed to just one item). `GlobalMetaData` components are only + /// supposed to show up right below the crate root. GlobalMetaData(InternedString), } diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index cdbeb8a4a545d..978a5556d31bf 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -842,7 +842,7 @@ impl<'hir> Map<'hir> { } /// Returns the nearest enclosing scope. A scope is roughly an item or block. - pub fn get_enclosing_scope(&self, id: HirId) -> Option { + pub fn get_enclosing_scope(&self, hir_id: HirId) -> Option { self.walk_parent_nodes(hir_id, |node| match *node { Node::Item(i) => { match i.node { @@ -880,14 +880,14 @@ impl<'hir> Map<'hir> { } /// Returns the defining scope for an existential type definition. - pub fn get_defining_scope(&self, id: NodeId) -> Option { + pub fn get_defining_scope(&self, id: HirId) -> Option { let mut scope = id; loop { scope = self.get_enclosing_scope(scope)?; - if scope == CRATE_NODE_ID { - return Some(CRATE_NODE_ID); + if scope == CRATE_HIR_ID { + return Some(CRATE_HIR_ID); } - match self.get(scope) { + match self.get_by_hir_id(scope) { Node::Item(i) => { match i.node { ItemKind::Existential(ExistTy { impl_trait_fn: None, .. }) => {} diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 20968ec6a63be..f884651e8be32 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1780,7 +1780,7 @@ pub struct ImplItem { pub span: Span, } -/// Represents different contents within `impl`s +/// Represents different contents within `impl`s. #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum ImplItemKind { /// An associated constant of the given type, set to the constant result @@ -1794,7 +1794,7 @@ pub enum ImplItemKind { Existential(GenericBounds), } -// Bind a type to an associated type: `A=Foo`. +// Bind a type to an associated type (`A = Foo`). #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct TypeBinding { pub hir_id: HirId, diff --git a/src/librustc/ich/impls_syntax.rs b/src/librustc/ich/impls_syntax.rs index af53f686ae548..0cdd9a863ccb8 100644 --- a/src/librustc/ich/impls_syntax.rs +++ b/src/librustc/ich/impls_syntax.rs @@ -408,7 +408,7 @@ impl_stable_hash_for!(enum ::syntax_pos::hygiene::CompilerDesugaringKind { Async, Await, QuestionMark, - ExistentialReturnType, + ExistentialType, ForLoop, TryBlock }); diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 2127fbbd56e93..50f85ea7770a4 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -953,14 +953,13 @@ pub fn may_define_existential_type( ); // Named existential types can be defined by any siblings or children of siblings. - let scope_node_id = tcx.hir() - .get_defining_scope(tcx.hir().hir_to_node_id(opaque_hir_id)) + let scope = tcx.hir() + .get_defining_scope(opaque_hir_id) .expect("could not get defining scope"); - let scope_id = tcx.hir().node_to_hir_id(scope_node_id); // We walk up the node tree until we hit the root or the scope of the opaque type. - while hir_id != scope_id && hir_id != hir::CRATE_HIR_ID { + while hir_id != scope && hir_id != hir::CRATE_HIR_ID { hir_id = tcx.hir().get_parent_item(hir_id); } // Syntactically, we are allowed to define the concrete type if: - hir_id == scope_id + hir_id == scope } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index fe24eab9f4439..f4f7456a97ad6 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -716,23 +716,14 @@ impl<'a> ReplaceBodyWithLoop<'a> { ast::GenericArg::Type(ty) => Some(ty), _ => None, }); - let any_assoc_ty_bounds = data.constraints.iter().any(|c| { - if let ast::AssocTyConstraintKind::Bound { .. } = c.kind { - true - } else { - false - } - }); - any_assoc_ty_bounds || any_involves_impl_trait(types.into_iter()) || - any_involves_impl_trait(data.constraints.iter().filter_map(|c| { - if let ast::AssocTyConstraintKind::Equality { ref ty } - = c.kind { - Some(ty) - } else { - None + data.constraints.iter().any(|c| { + match c.kind { + ast::AssocTyConstraintKind::Bound { .. } => true, + ast::AssocTyConstraintKind::Equality { ref ty } => + involves_impl_trait(ty), } - })) + }) }, Some(&ast::GenericArgs::Parenthesized(ref data)) => { any_involves_impl_trait(data.inputs.iter()) || diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 61a860aef8597..18f3c0285c210 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2533,7 +2533,7 @@ impl<'a> Resolver<'a> { self.with_current_self_item(item, |this| { this.with_generic_param_rib(HasGenericParams(generics, ItemRibKind), |this| { let item_def_id = this.definitions.local_def_id(item.id); - this.with_self_rib(Def::SelfTy(Some(item_def_id), None), |this| { + this.with_self_rib(Res::SelfTy(Some(item_def_id), None), |this| { visit::walk_item(this, item) }) }) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 5ddb2c974ac02..e37ad77b086fd 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -764,7 +764,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let mut dup_bindings = FxHashMap::default(); for binding in &assoc_bindings { // Specify type to assert that error was already reported in `Err` case. - let _ = + let _: Result<_, ErrorReported> = self.add_predicates_for_ast_type_binding( trait_ref.hir_ref_id, poly_trait_ref, @@ -933,8 +933,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } /// Translates the AST's notion of ty param bounds (which are an enum consisting of a newtyped - /// `Ty` or a region) to ty's notion of ty param bounds, which can either be user-defined traits - /// or the built-in trait `Send`. + /// `Ty` or a region) to ty's notion of ty param bounds (which can either be user-defined traits + /// or the built-in trait `Sized`). pub fn compute_bounds(&self, param_ty: Ty<'tcx>, ast_bounds: &[hir::GenericBound], diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 90ab596363bff..2751cd0a37ec0 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -1650,24 +1650,23 @@ fn find_existential_constraints<'a, 'tcx>( } } - let node_id = tcx.hir().as_local_node_id(def_id).unwrap(); - let scope_node_id = tcx.hir() - .get_defining_scope(node_id) + 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_id = tcx.hir().node_to_hir_id(scope_node_id); let mut locator = ConstraintLocator { def_id, tcx, found: None, }; - debug!("find_existential_constraints: scope_id={:?}", scope_id); + debug!("find_existential_constraints: scope={:?}", scope); - if scope_id == hir::CRATE_HIR_ID { + if scope == hir::CRATE_HIR_ID { intravisit::walk_crate(&mut locator, tcx.hir().krate()); } else { - debug!("find_existential_constraints: scope={:?}", tcx.hir().get_by_hir_id(scope_id)); - match tcx.hir().get_by_hir_id(scope_id) { + debug!("find_existential_constraints: scope={:?}", tcx.hir().get_by_hir_id(scope)); + match tcx.hir().get_by_hir_id(scope) { Node::Item(ref it) => intravisit::walk_item(&mut locator, it), Node::ImplItem(ref it) => intravisit::walk_impl_item(&mut locator, it), Node::TraitItem(ref it) => intravisit::walk_trait_item(&mut locator, it), diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 161e426604e94..af283e6c0bc6f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2445,7 +2445,7 @@ pub struct PolyTrait { /// A representation of a type suitable for hyperlinking purposes. Ideally, one can get the original /// type out of the AST/`TyCtxt` given one of these, if more information is needed. Most -/// importanntly, it does not preserve mutability or boxes. +/// importantly, it does not preserve mutability or boxes. #[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Debug, Hash)] pub enum Type { /// Structs/enums/traits (most that would be an `hir::TyKind::Path`). diff --git a/src/libsyntax_pos/hygiene.rs b/src/libsyntax_pos/hygiene.rs index 213993996a63c..b827416ab53c2 100644 --- a/src/libsyntax_pos/hygiene.rs +++ b/src/libsyntax_pos/hygiene.rs @@ -714,7 +714,7 @@ pub enum CompilerDesugaringKind { /// Desugaring of an `impl Trait` in return type position /// to an `existential type Foo: Trait;` and replacing the /// `impl Trait` with `Foo`. - ExistentialReturnType, + ExistentialType, Async, Await, ForLoop, @@ -728,7 +728,7 @@ impl CompilerDesugaringKind { CompilerDesugaringKind::Await => "await", CompilerDesugaringKind::QuestionMark => "?", CompilerDesugaringKind::TryBlock => "try block", - CompilerDesugaringKind::ExistentialReturnType => "existential type", + CompilerDesugaringKind::ExistentialType => "existential type", CompilerDesugaringKind::ForLoop => "for loop", }) } diff --git a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr index 44fa9e89d3502..db421e6973d07 100644 --- a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr +++ b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr @@ -6,4 +6,3 @@ LL | for<'a> <_2 as Iterator>::Item: for<'b> Lam<&'a &'b u8, App = _0>, error: aborting due to previous error -For more information about this error, try `rustc --explain E0316`. diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr index 1405cb1b4736c..c25f12d008703 100644 --- a/src/test/ui/associated-types/associated-types-path-2.stderr +++ b/src/test/ui/associated-types/associated-types-path-2.stderr @@ -49,7 +49,7 @@ error[E0308]: mismatched types | LL | let _: i32 = f2(2i32); | ^^^^^^^^ expected i32, found u32 -help: you can convert an `u32` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `i32` or panic if it the converted value wouldn't fit | LL | let _: i32 = f2(2i32).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr index bffb11640744c..e881201ddfcc0 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr +++ b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr @@ -1,5 +1,80 @@ -error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-closures-two-mut.rs:12:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) + --> $DIR/borrowck-closures-two-mut.rs:14:24 + | +LL | let c1 = to_fn_mut(|| x = 4); + | -- - previous borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| x = 5); + | ^^ - borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) + --> $DIR/borrowck-closures-two-mut.rs:26:24 + | +LL | let c1 = to_fn_mut(|| set(&mut x)); + | -- - previous borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| set(&mut x)); + | ^^ - borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) + --> $DIR/borrowck-closures-two-mut.rs:34:24 + | +LL | let c1 = to_fn_mut(|| x = 5); + | -- - previous borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| set(&mut x)); + | ^^ - borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) + --> $DIR/borrowck-closures-two-mut.rs:42:24 + | +LL | let c1 = to_fn_mut(|| x = 5); + | -- - previous borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) + | ^^ - borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) + --> $DIR/borrowck-closures-two-mut.rs:55:24 + | +LL | let c1 = to_fn_mut(|| set(&mut *x.f)); + | -- - previous borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let c2 = to_fn_mut(|| set(&mut *x.f)); + | ^^ - borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) + --> $DIR/borrowck-closures-two-mut.rs:14:24 | LL | let c1 = to_fn_mut(|| x = 4); | -- - first borrow occurs due to use of `x` in closure @@ -9,11 +84,12 @@ LL | let c2 = to_fn_mut(|| x = 5); | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here +LL | LL | drop((c1, c2)); | -- first borrow later used here -error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-closures-two-mut.rs:23:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) + --> $DIR/borrowck-closures-two-mut.rs:26:24 | LL | let c1 = to_fn_mut(|| set(&mut x)); | -- - first borrow occurs due to use of `x` in closure @@ -23,11 +99,12 @@ LL | let c2 = to_fn_mut(|| set(&mut x)); | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here +LL | LL | drop((c1, c2)); | -- first borrow later used here -error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-closures-two-mut.rs:30:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) + --> $DIR/borrowck-closures-two-mut.rs:34:24 | LL | let c1 = to_fn_mut(|| x = 5); | -- - first borrow occurs due to use of `x` in closure @@ -37,11 +114,12 @@ LL | let c2 = to_fn_mut(|| set(&mut x)); | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here +LL | LL | drop((c1, c2)); | -- first borrow later used here -error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-closures-two-mut.rs:37:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) + --> $DIR/borrowck-closures-two-mut.rs:42:24 | LL | let c1 = to_fn_mut(|| x = 5); | -- - first borrow occurs due to use of `x` in closure @@ -51,12 +129,12 @@ LL | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nes | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -LL | +... LL | drop((c1, c2)); | -- first borrow later used here -error[E0499]: cannot borrow `x` as mutable more than once at a time - --> $DIR/borrowck-closures-two-mut.rs:49:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) + --> $DIR/borrowck-closures-two-mut.rs:55:24 | LL | let c1 = to_fn_mut(|| set(&mut *x.f)); | -- - first borrow occurs due to use of `x` in closure @@ -66,10 +144,10 @@ LL | let c2 = to_fn_mut(|| set(&mut *x.f)); | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -LL | +... LL | drop((c1, c2)); | -- first borrow later used here -error: aborting due to 5 previous errors +error: aborting due to 10 previous errors For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/borrowck/borrowck-reinit.stderr b/src/test/ui/borrowck/borrowck-reinit.stderr index f8f14b6435f08..3618a7cb2cd39 100644 --- a/src/test/ui/borrowck/borrowck-reinit.stderr +++ b/src/test/ui/borrowck/borrowck-reinit.stderr @@ -1,5 +1,15 @@ -error[E0382]: use of moved value: `x` - --> $DIR/borrowck-reinit.rs:6:16 +error[E0382]: use of moved value: `x` (Ast) + --> $DIR/borrowck-reinit.rs:8:16 + | +LL | drop(x); + | - value moved here +LL | let _ = (1,x); + | ^ value used here after move + | + = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `x` (Mir) + --> $DIR/borrowck-reinit.rs:8:16 | LL | let mut x = Box::new(0); | ----- move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait @@ -9,6 +19,6 @@ LL | drop(x); LL | let _ = (1,x); | ^ value used here after move -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/borrowck-storage-dead.stderr b/src/test/ui/borrowck/borrowck-storage-dead.stderr index 5b9f49c2e7c92..c291ed224eb3c 100644 --- a/src/test/ui/borrowck/borrowck-storage-dead.stderr +++ b/src/test/ui/borrowck/borrowck-storage-dead.stderr @@ -1,9 +1,15 @@ -error[E0381]: use of possibly uninitialized variable: `x` - --> $DIR/borrowck-storage-dead.rs:16:17 +error[E0381]: use of possibly uninitialized variable: `x` (Ast) + --> $DIR/borrowck-storage-dead.rs:18:17 | LL | let _ = x + 1; | ^ use of possibly uninitialized `x` -error: aborting due to previous error +error[E0381]: use of possibly uninitialized variable: `x` (Mir) + --> $DIR/borrowck-storage-dead.rs:18:17 + | +LL | let _ = x + 1; + | ^ use of possibly uninitialized `x` + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/borrowck/immutable-arg.stderr b/src/test/ui/borrowck/immutable-arg.stderr index 7255ca327e753..8b21e92666674 100644 --- a/src/test/ui/borrowck/immutable-arg.stderr +++ b/src/test/ui/borrowck/immutable-arg.stderr @@ -1,11 +1,19 @@ -error[E0384]: cannot assign to immutable argument `_x` - --> $DIR/immutable-arg.rs:2:5 +error[E0384]: cannot assign twice to immutable variable `_x` (Ast) + --> $DIR/immutable-arg.rs:4:5 + | +LL | fn foo(_x: u32) { + | -- first assignment to `_x` +LL | _x = 4; + | ^^^^^^ cannot assign twice to immutable variable + +error[E0384]: cannot assign to immutable argument `_x` (Mir) + --> $DIR/immutable-arg.rs:4:5 | LL | fn foo(_x: u32) { | -- help: make this binding mutable: `mut _x` LL | _x = 4; | ^^^^^^ cannot assign to immutable argument -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr index 422d1605aa46b..fd4d318b5ddf1 100644 --- a/src/test/ui/borrowck/issue-41962.stderr +++ b/src/test/ui/borrowck/issue-41962.stderr @@ -1,11 +1,29 @@ -error[E0382]: use of moved value - --> $DIR/issue-41962.rs:5:21 +error[E0382]: use of partially moved value: `maybe` (Ast) + --> $DIR/issue-41962.rs:7:30 + | +LL | if let Some(thing) = maybe { + | ----- ^^^^^ value used here after move + | | + | value moved here + | + = note: move occurs because the value has type `std::vec::Vec`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `(maybe as std::prelude::v1::Some).0` (Ast) + --> $DIR/issue-41962.rs:7:21 + | +LL | if let Some(thing) = maybe { + | ^^^^^ value moved here in previous iteration of loop + | + = note: move occurs because the value has type `std::vec::Vec`, which does not implement the `Copy` trait + +error[E0382]: use of moved value (Mir) + --> $DIR/issue-41962.rs:7:21 | LL | if let Some(thing) = maybe { | ^^^^^ value moved here, in previous iteration of loop | = note: move occurs because value has type `std::vec::Vec`, which does not implement the `Copy` trait -error: aborting due to previous error +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/const-generics/const-param-before-other-params.stderr b/src/test/ui/const-generics/const-param-before-other-params.stderr index 33f981d1eba9b..78f129e79ea24 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.stderr +++ b/src/test/ui/const-generics/const-param-before-other-params.stderr @@ -4,17 +4,17 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ -error: lifetime parameters must be declared prior to const parameters +error: type parameters must be declared prior to const parameters --> $DIR/const-param-before-other-params.rs:4:21 | -LL | fn bar(_: &'a ()) { - | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>` +LL | fn foo(_: &T) { + | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `` -error: type parameters must be declared prior to const parameters +error: lifetime parameters must be declared prior to const parameters --> $DIR/const-param-before-other-params.rs:8:21 | -LL | fn foo(_: &T) { - | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `` +LL | fn bar(_: &'a ()) { + | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>` error: aborting due to 2 previous errors diff --git a/src/test/ui/deprecation/deprecation-in-staged-api.rs b/src/test/ui/deprecation/deprecation-in-staged-api.rs index bcc17c789f551..f667de83b56d4 100644 --- a/src/test/ui/deprecation/deprecation-in-staged-api.rs +++ b/src/test/ui/deprecation/deprecation-in-staged-api.rs @@ -1,8 +1,8 @@ -// #[deprecated] can't be used in staged api +// #[deprecated] cannot be used in staged API #![feature(staged_api)] #![stable(feature = "stable_test_feature", since = "1.0.0")] #[deprecated] -fn main() { } //~ERROR `#[deprecated]` cannot be used in staged api +fn main() { } //~ ERROR `#[deprecated]` cannot be used in staged API diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs index 6b4f5005d48f0..3d75251e15616 100644 --- a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.rs @@ -10,61 +10,62 @@ impl Tr1 for S1 { type As1 = S2; } trait _Tr3 { type A: Iterator; - //~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + //~^ ERROR associated type bounds are unstable type B: Iterator; - //~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + //~^ ERROR associated type bounds are unstable } struct _St1> { -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable outest: T, outer: T::As1, inner: ::As2, } enum _En1> { -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable Outest(T), Outer(T::As1), Inner(::As2), } union _Un1> { -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable outest: T, outer: T::As1, inner: ::As2, } type _TaWhere1 where T: Iterator = T; -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable fn _apit(_: impl Tr1) {} -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable fn _apit_dyn(_: &dyn Tr1) {} -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable fn _rpit() -> impl Tr1 { S1 } -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable + fn _rpit_dyn() -> Box> { Box::new(S1) } -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable const _cdef: impl Tr1 = S1; -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable //~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. // const _cdef_dyn: &dyn Tr1 = &S1; static _sdef: impl Tr1 = S1; -//~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] +//~^ ERROR associated type bounds are unstable //~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. // static _sdef_dyn: &dyn Tr1 = &S1; fn main() { let _: impl Tr1 = S1; - //~^ ERROR associated type bounds are unstable (see issue #52662) [E0658] + //~^ ERROR associated type bounds are unstable //~| ERROR `impl Trait` not allowed outside of function and inherent method return types [E0562] // FIXME: uncomment when `impl_trait_in_bindings` feature is fixed. // let _: &dyn Tr1 = &S1; diff --git a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr index 9b83c1cfb33d1..702f61262df69 100644 --- a/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr +++ b/src/test/ui/feature-gates/feature-gate-associated_type_bounds.stderr @@ -1,109 +1,122 @@ -error[E0658]: associated type bounds are unstable (see issue #52662) +error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:12:22 | LL | type A: Iterator; | ^^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) +error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:15:22 | LL | type B: Iterator; | ^^^^^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) +error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:19:20 | LL | struct _St1> { | ^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) +error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:26:18 | LL | enum _En1> { | ^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) +error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:33:19 | LL | union _Un1> { | ^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) +error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:40:37 | LL | type _TaWhere1 where T: Iterator = T; | ^^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) +error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:43:22 | LL | fn _apit(_: impl Tr1) {} | ^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) +error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:45:26 | LL | fn _apit_dyn(_: &dyn Tr1) {} | ^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) +error[E0658]: associated type bounds are unstable --> $DIR/feature-gate-associated_type_bounds.rs:48:24 | LL | fn _rpit() -> impl Tr1 { S1 } | ^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) - --> $DIR/feature-gate-associated_type_bounds.rs:50:31 +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:51:31 | LL | fn _rpit_dyn() -> Box> { Box::new(S1) } | ^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) - --> $DIR/feature-gate-associated_type_bounds.rs:53:23 +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:54:23 | LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) - --> $DIR/feature-gate-associated_type_bounds.rs:59:24 +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:60:24 | LL | static _sdef: impl Tr1 = S1; | ^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable -error[E0658]: associated type bounds are unstable (see issue #52662) - --> $DIR/feature-gate-associated_type_bounds.rs:66:21 +error[E0658]: associated type bounds are unstable + --> $DIR/feature-gate-associated_type_bounds.rs:67:21 | LL | let _: impl Tr1 = S1; | ^^^^^^^^^ | + = note: for more information, see https://github.com/rust-lang/rust/issues/52662 = help: add #![feature(associated_type_bounds)] to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-associated_type_bounds.rs:53:14 + --> $DIR/feature-gate-associated_type_bounds.rs:54:14 | LL | const _cdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ @@ -111,7 +124,7 @@ LL | const _cdef: impl Tr1 = S1; = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-associated_type_bounds.rs:59:15 + --> $DIR/feature-gate-associated_type_bounds.rs:60:15 | LL | static _sdef: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ @@ -119,7 +132,7 @@ LL | static _sdef: impl Tr1 = S1; = help: add #![feature(impl_trait_in_bindings)] to the crate attributes to enable error[E0562]: `impl Trait` not allowed outside of function and inherent method return types - --> $DIR/feature-gate-associated_type_bounds.rs:66:12 + --> $DIR/feature-gate-associated_type_bounds.rs:67:12 | LL | let _: impl Tr1 = S1; | ^^^^^^^^^^^^^^^^^^^ @@ -128,5 +141,5 @@ LL | let _: impl Tr1 = S1; error: aborting due to 16 previous errors -Some errors occurred: E0562, E0658. +Some errors have detailed explanations: E0562, E0658. For more information about an error, try `rustc --explain E0562`. diff --git a/src/test/ui/generator/yield-while-local-borrowed.stderr b/src/test/ui/generator/yield-while-local-borrowed.stderr index c1513ef9b7157..56f425b7e70a0 100644 --- a/src/test/ui/generator/yield-while-local-borrowed.stderr +++ b/src/test/ui/generator/yield-while-local-borrowed.stderr @@ -1,21 +1,39 @@ -error[E0626]: borrow may still be in use when generator yields - --> $DIR/yield-while-local-borrowed.rs:13:17 +error[E0626]: borrow may still be in use when generator yields (Ast) + --> $DIR/yield-while-local-borrowed.rs:15:22 + | +LL | let a = &mut 3; + | ^ +... +LL | yield(); + | ------- possible yield occurs here + +error[E0626]: borrow may still be in use when generator yields (Ast) + --> $DIR/yield-while-local-borrowed.rs:43:22 + | +LL | let b = &a; + | ^ +... +LL | yield(); + | ------- possible yield occurs here + +error[E0626]: borrow may still be in use when generator yields (Mir) + --> $DIR/yield-while-local-borrowed.rs:15:17 | LL | let a = &mut 3; | ^^^^^^ -LL | +... LL | yield(); | ------- possible yield occurs here -error[E0626]: borrow may still be in use when generator yields - --> $DIR/yield-while-local-borrowed.rs:40:21 +error[E0626]: borrow may still be in use when generator yields (Mir) + --> $DIR/yield-while-local-borrowed.rs:43:21 | LL | let b = &a; | ^^ -LL | +... LL | yield(); | ------- possible yield occurs here -error: aborting due to 2 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0626`. diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr index 3300db58d44c3..9dafe1c24f1c2 100644 --- a/src/test/ui/indexing-requires-a-uint.stderr +++ b/src/test/ui/indexing-requires-a-uint.stderr @@ -12,7 +12,7 @@ error[E0308]: mismatched types | LL | bar::(i); // i should not be re-coerced back to an isize | ^ expected isize, found usize -help: you can convert an `usize` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `isize` or panic if it the converted value wouldn't fit | LL | bar::(i.try_into().unwrap()); // i should not be re-coerced back to an isize | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/integer-literal-suffix-inference.stderr b/src/test/ui/integer-literal-suffix-inference.stderr index 80b601dc4394b..b5b3f27f0e6cd 100644 --- a/src/test/ui/integer-literal-suffix-inference.stderr +++ b/src/test/ui/integer-literal-suffix-inference.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | id_i8(a16); | ^^^ expected i8, found i16 -help: you can convert an `i16` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i16` to `i8` or panic if it the converted value wouldn't fit | LL | id_i8(a16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ error[E0308]: mismatched types | LL | id_i8(a32); | ^^^ expected i8, found i32 -help: you can convert an `i32` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `i8` or panic if it the converted value wouldn't fit | LL | id_i8(a32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ error[E0308]: mismatched types | LL | id_i8(a64); | ^^^ expected i8, found i64 -help: you can convert an `i64` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i8` or panic if it the converted value wouldn't fit | LL | id_i8(a64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ error[E0308]: mismatched types | LL | id_i16(a32); | ^^^ expected i16, found i32 -help: you can convert an `i32` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `i16` or panic if it the converted value wouldn't fit | LL | id_i16(a32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ error[E0308]: mismatched types | LL | id_i16(a64); | ^^^ expected i16, found i64 -help: you can convert an `i64` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i16` or panic if it the converted value wouldn't fit | LL | id_i16(a64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ error[E0308]: mismatched types | LL | id_i32(a64); | ^^^ expected i32, found i64 -help: you can convert an `i64` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i32` or panic if it the converted value wouldn't fit | LL | id_i32(a64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -117,7 +117,7 @@ error[E0308]: mismatched types | LL | id_i8(c16); | ^^^ expected i8, found i16 -help: you can convert an `i16` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i16` to `i8` or panic if it the converted value wouldn't fit | LL | id_i8(c16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ error[E0308]: mismatched types | LL | id_i8(c32); | ^^^ expected i8, found i32 -help: you can convert an `i32` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `i8` or panic if it the converted value wouldn't fit | LL | id_i8(c32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ error[E0308]: mismatched types | LL | id_i8(c64); | ^^^ expected i8, found i64 -help: you can convert an `i64` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i8` or panic if it the converted value wouldn't fit | LL | id_i8(c64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ error[E0308]: mismatched types | LL | id_i16(c32); | ^^^ expected i16, found i32 -help: you can convert an `i32` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `i16` or panic if it the converted value wouldn't fit | LL | id_i16(c32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ error[E0308]: mismatched types | LL | id_i16(c64); | ^^^ expected i16, found i64 -help: you can convert an `i64` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i16` or panic if it the converted value wouldn't fit | LL | id_i16(c64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -194,7 +194,7 @@ error[E0308]: mismatched types | LL | id_i32(c64); | ^^^ expected i32, found i64 -help: you can convert an `i64` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i32` or panic if it the converted value wouldn't fit | LL | id_i32(c64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ error[E0308]: mismatched types | LL | id_u8(b16); | ^^^ expected u8, found u16 -help: you can convert an `u16` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `u8` or panic if it the converted value wouldn't fit | LL | id_u8(b16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +241,7 @@ error[E0308]: mismatched types | LL | id_u8(b32); | ^^^ expected u8, found u32 -help: you can convert an `u32` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `u8` or panic if it the converted value wouldn't fit | LL | id_u8(b32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -251,7 +251,7 @@ error[E0308]: mismatched types | LL | id_u8(b64); | ^^^ expected u8, found u64 -help: you can convert an `u64` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `u8` or panic if it the converted value wouldn't fit | LL | id_u8(b64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -270,7 +270,7 @@ error[E0308]: mismatched types | LL | id_u16(b32); | ^^^ expected u16, found u32 -help: you can convert an `u32` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `u16` or panic if it the converted value wouldn't fit | LL | id_u16(b32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -280,7 +280,7 @@ error[E0308]: mismatched types | LL | id_u16(b64); | ^^^ expected u16, found u64 -help: you can convert an `u64` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `u16` or panic if it the converted value wouldn't fit | LL | id_u16(b64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -308,7 +308,7 @@ error[E0308]: mismatched types | LL | id_u32(b64); | ^^^ expected u32, found u64 -help: you can convert an `u64` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `u32` or panic if it the converted value wouldn't fit | LL | id_u32(b64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-13359.stderr b/src/test/ui/issues/issue-13359.stderr index 7cfd754f72d8e..b16b7a5b2cf04 100644 --- a/src/test/ui/issues/issue-13359.stderr +++ b/src/test/ui/issues/issue-13359.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | foo(1*(1 as isize)); | ^^^^^^^^^^^^^^ expected i16, found isize -help: you can convert an `isize` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `i16` or panic if it the converted value wouldn't fit | LL | foo((1*(1 as isize)).try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ error[E0308]: mismatched types | LL | bar(1*(1 as usize)); | ^^^^^^^^^^^^^^ expected u32, found usize -help: you can convert an `usize` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `u32` or panic if it the converted value wouldn't fit | LL | bar((1*(1 as usize)).try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-31910.stderr b/src/test/ui/issues/issue-31910.stderr index e7555b958a3d4..8dd9287ffec79 100644 --- a/src/test/ui/issues/issue-31910.stderr +++ b/src/test/ui/issues/issue-31910.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | X = Trait::Number, | ^^^^^^^^^^^^^ expected isize, found i32 -help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `isize` or panic if it the converted value wouldn't fit | LL | X = Trait::Number.try_into().unwrap(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-45697-1.stderr b/src/test/ui/issues/issue-45697-1.stderr index 30c69f19658c8..854e18003f330 100644 --- a/src/test/ui/issues/issue-45697-1.stderr +++ b/src/test/ui/issues/issue-45697-1.stderr @@ -1,4 +1,12 @@ -error[E0503]: cannot use `*y.pointer` because it was mutably borrowed +error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Ast) + --> $DIR/issue-45697-1.rs:20:9 + | +LL | let z = copy_borrowed_ptr(&mut y); + | - borrow of `*y.pointer` occurs here +LL | *y.pointer += 1; + | ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here + +error[E0503]: cannot use `*y.pointer` because it was mutably borrowed (Mir) --> $DIR/issue-45697-1.rs:20:9 | LL | let z = copy_borrowed_ptr(&mut y); @@ -9,7 +17,7 @@ LL | *y.pointer += 1; LL | *z.pointer += 1; | --------------- borrow later used here -error[E0506]: cannot assign to `*y.pointer` because it is borrowed +error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Mir) --> $DIR/issue-45697-1.rs:20:9 | LL | let z = copy_borrowed_ptr(&mut y); @@ -20,7 +28,7 @@ LL | *y.pointer += 1; LL | *z.pointer += 1; | --------------- borrow later used here -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0503, E0506. For more information about an error, try `rustc --explain E0503`. diff --git a/src/test/ui/issues/issue-45697.stderr b/src/test/ui/issues/issue-45697.stderr index 26749d36f0b7b..01ae416b1cf14 100644 --- a/src/test/ui/issues/issue-45697.stderr +++ b/src/test/ui/issues/issue-45697.stderr @@ -1,4 +1,12 @@ -error[E0503]: cannot use `*y.pointer` because it was mutably borrowed +error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Ast) + --> $DIR/issue-45697.rs:20:9 + | +LL | let z = copy_borrowed_ptr(&mut y); + | - borrow of `*y.pointer` occurs here +LL | *y.pointer += 1; + | ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here + +error[E0503]: cannot use `*y.pointer` because it was mutably borrowed (Mir) --> $DIR/issue-45697.rs:20:9 | LL | let z = copy_borrowed_ptr(&mut y); @@ -9,7 +17,7 @@ LL | *y.pointer += 1; LL | *z.pointer += 1; | --------------- borrow later used here -error[E0506]: cannot assign to `*y.pointer` because it is borrowed +error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Mir) --> $DIR/issue-45697.rs:20:9 | LL | let z = copy_borrowed_ptr(&mut y); @@ -20,7 +28,7 @@ LL | *y.pointer += 1; LL | *z.pointer += 1; | --------------- borrow later used here -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0503, E0506. For more information about an error, try `rustc --explain E0503`. diff --git a/src/test/ui/issues/issue-46471-1.stderr b/src/test/ui/issues/issue-46471-1.stderr index b09f31729a5fd..51026c9f2d834 100644 --- a/src/test/ui/issues/issue-46471-1.stderr +++ b/src/test/ui/issues/issue-46471-1.stderr @@ -1,5 +1,16 @@ -error[E0597]: `z` does not live long enough - --> $DIR/issue-46471-1.rs:4:9 +error[E0597]: `z` does not live long enough (Ast) + --> $DIR/issue-46471-1.rs:6:14 + | +LL | &mut z + | ^ borrowed value does not live long enough +LL | }; + | - `z` dropped here while still borrowed +... +LL | } + | - borrowed value needs to live until here + +error[E0597]: `z` does not live long enough (Mir) + --> $DIR/issue-46471-1.rs:6:9 | LL | &mut z | ^^^^^^ @@ -9,6 +20,6 @@ LL | &mut z LL | }; | - `z` dropped here while still borrowed -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issues/issue-46471.stderr b/src/test/ui/issues/issue-46471.stderr index 935414c1f3f9d..90202e307eb11 100644 --- a/src/test/ui/issues/issue-46471.stderr +++ b/src/test/ui/issues/issue-46471.stderr @@ -1,9 +1,21 @@ -error[E0515]: cannot return reference to local variable `x` - --> $DIR/issue-46471.rs:3:5 +error[E0597]: `x` does not live long enough (Ast) + --> $DIR/issue-46471.rs:5:6 + | +LL | &x + | ^ borrowed value does not live long enough +... +LL | } + | - borrowed value only lives until here + | + = note: borrowed value must be valid for the static lifetime... + +error[E0515]: cannot return reference to local variable `x` (Mir) + --> $DIR/issue-46471.rs:5:5 | LL | &x | ^^ returns a reference to data owned by the current function -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0515`. +Some errors have detailed explanations: E0515, E0597. +For more information about an error, try `rustc --explain E0515`. diff --git a/src/test/ui/issues/issue-46472.stderr b/src/test/ui/issues/issue-46472.stderr index 6e561e03a8b7a..0cc93a081b2af 100644 --- a/src/test/ui/issues/issue-46472.stderr +++ b/src/test/ui/issues/issue-46472.stderr @@ -1,5 +1,20 @@ -error[E0515]: cannot return reference to temporary value - --> $DIR/issue-46472.rs:2:5 +error[E0597]: borrowed value does not live long enough (Ast) + --> $DIR/issue-46472.rs:4:10 + | +LL | &mut 4 + | ^ temporary value does not live long enough +... +LL | } + | - temporary value only lives until here + | +note: borrowed value must be valid for the lifetime 'a as defined on the function body at 3:8... + --> $DIR/issue-46472.rs:3:8 + | +LL | fn bar<'a>() -> &'a mut u32 { + | ^^ + +error[E0515]: cannot return reference to temporary value (Mir) + --> $DIR/issue-46472.rs:4:5 | LL | &mut 4 | ^^^^^- @@ -7,6 +22,7 @@ LL | &mut 4 | | temporary value created here | returns a reference to data owned by the current function -error: aborting due to previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0515`. +Some errors have detailed explanations: E0515, E0597. +For more information about an error, try `rustc --explain E0515`. diff --git a/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr b/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr index c646912d3b679..e15290f0b9ee9 100644 --- a/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr @@ -1,5 +1,36 @@ -error[E0384]: cannot assign twice to immutable variable `x` - --> $DIR/liveness-assign-imm-local-notes.rs:10:9 +error[E0384]: cannot assign twice to immutable variable `x` (Ast) + --> $DIR/liveness-assign-imm-local-notes.rs:13:9 + | +LL | x = 2; + | ----- first assignment to `x` +LL | x = 3; + | ^^^^^ cannot assign twice to immutable variable + +error[E0384]: cannot assign twice to immutable variable `x` (Ast) + --> $DIR/liveness-assign-imm-local-notes.rs:25:13 + | +LL | x = 2; + | ----- first assignment to `x` +LL | x = 3; + | ^^^^^ cannot assign twice to immutable variable + +error[E0384]: cannot assign twice to immutable variable `x` (Ast) + --> $DIR/liveness-assign-imm-local-notes.rs:35:13 + | +LL | x = 1; + | ^^^^^ cannot assign twice to immutable variable + +error[E0384]: cannot assign twice to immutable variable `x` (Ast) + --> $DIR/liveness-assign-imm-local-notes.rs:38:13 + | +LL | x = 1; + | ----- first assignment to `x` +... +LL | x = 2; + | ^^^^^ cannot assign twice to immutable variable + +error[E0384]: cannot assign twice to immutable variable `x` (Mir) + --> $DIR/liveness-assign-imm-local-notes.rs:13:9 | LL | let x; | - help: make this binding mutable: `mut x` @@ -9,8 +40,8 @@ LL | x = 2; LL | x = 3; | ^^^^^ cannot assign twice to immutable variable -error[E0384]: cannot assign twice to immutable variable `x` - --> $DIR/liveness-assign-imm-local-notes.rs:21:13 +error[E0384]: cannot assign twice to immutable variable `x` (Mir) + --> $DIR/liveness-assign-imm-local-notes.rs:25:13 | LL | let x; | - help: make this binding mutable: `mut x` @@ -20,8 +51,8 @@ LL | x = 2; LL | x = 3; | ^^^^^ cannot assign twice to immutable variable -error[E0384]: cannot assign twice to immutable variable `x` - --> $DIR/liveness-assign-imm-local-notes.rs:30:13 +error[E0384]: cannot assign twice to immutable variable `x` (Mir) + --> $DIR/liveness-assign-imm-local-notes.rs:35:13 | LL | let x; | - help: make this binding mutable: `mut x` @@ -29,18 +60,18 @@ LL | let x; LL | x = 1; | ^^^^^ cannot assign twice to immutable variable -error[E0384]: cannot assign twice to immutable variable `x` - --> $DIR/liveness-assign-imm-local-notes.rs:32:13 +error[E0384]: cannot assign twice to immutable variable `x` (Mir) + --> $DIR/liveness-assign-imm-local-notes.rs:38:13 | LL | let x; | - help: make this binding mutable: `mut x` ... LL | x = 1; | ----- first assignment to `x` -LL | } else { +... LL | x = 2; | ^^^^^ cannot assign twice to immutable variable -error: aborting due to 4 previous errors +error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index b1bd749bef4a2..49c72a655e57a 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -11,7 +11,7 @@ error[E0308]: mismatched types | LL | let y: usize = x.foo(); | ^^^^^^^ expected usize, found isize -help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `usize` or panic if it the converted value wouldn't fit | LL | let y: usize = x.foo().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index 881d9fd32029e..1a81df8e2c464 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -6,7 +6,7 @@ LL | $arr.len() * size_of($arr[0])); ... LL | write!(hello); | -------------- in this macro invocation -help: you can convert an `usize` to `u64` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `u64` or panic if it the converted value wouldn't fit | LL | ($arr.len() * size_of($arr[0])).try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/moves/moves-based-on-type-tuple.stderr b/src/test/ui/moves/moves-based-on-type-tuple.stderr index 2e1ddbdf57f98..c49dbdab40210 100644 --- a/src/test/ui/moves/moves-based-on-type-tuple.stderr +++ b/src/test/ui/moves/moves-based-on-type-tuple.stderr @@ -1,5 +1,15 @@ -error[E0382]: use of moved value: `x` - --> $DIR/moves-based-on-type-tuple.rs:4:13 +error[E0382]: use of moved value: `x` (Ast) + --> $DIR/moves-based-on-type-tuple.rs:6:13 + | +LL | box (x, x) + | - ^ value used here after move + | | + | value moved here + | + = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `x` (Mir) + --> $DIR/moves-based-on-type-tuple.rs:6:13 | LL | fn dup(x: Box) -> Box<(Box,Box)> { | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait @@ -8,6 +18,6 @@ LL | box (x, x) | | | value moved here -error: aborting due to previous error +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/nll/get_default.stderr b/src/test/ui/nll/get_default.stderr index af79771e7e1b9..abb5343845b57 100644 --- a/src/test/ui/nll/get_default.stderr +++ b/src/test/ui/nll/get_default.stderr @@ -1,5 +1,41 @@ -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable - --> $DIR/get_default.rs:21:17 +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Ast) + --> $DIR/get_default.rs:23:17 + | +LL | match map.get() { + | --- immutable borrow occurs here +... +LL | map.set(String::new()); // Ideally, this would not error. + | ^^^ mutable borrow occurs here +... +LL | } + | - immutable borrow ends here + +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Ast) + --> $DIR/get_default.rs:35:17 + | +LL | match map.get() { + | --- immutable borrow occurs here +LL | Some(v) => { +LL | map.set(String::new()); // Both AST and MIR error here + | ^^^ mutable borrow occurs here +... +LL | } + | - immutable borrow ends here + +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Ast) + --> $DIR/get_default.rs:41:17 + | +LL | match map.get() { + | --- immutable borrow occurs here +... +LL | map.set(String::new()); // Ideally, just AST would error here + | ^^^ mutable borrow occurs here +... +LL | } + | - immutable borrow ends here + +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir) + --> $DIR/get_default.rs:23:17 | LL | fn ok(map: &mut Map) -> &String { | - let's call the lifetime of this reference `'1` @@ -11,10 +47,10 @@ LL | return v; | - returning this value requires that `*map` is borrowed for `'1` ... LL | map.set(String::new()); // Ideally, this would not error. - | ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^ mutable borrow occurs here -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable - --> $DIR/get_default.rs:32:17 +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir) + --> $DIR/get_default.rs:35:17 | LL | fn err(map: &mut Map) -> &String { | - let's call the lifetime of this reference `'1` @@ -23,13 +59,13 @@ LL | match map.get() { | --- immutable borrow occurs here LL | Some(v) => { LL | map.set(String::new()); // Both AST and MIR error here - | ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here -LL | + | ^^^ mutable borrow occurs here +... LL | return v; | - returning this value requires that `*map` is borrowed for `'1` -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable - --> $DIR/get_default.rs:37:17 +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir) + --> $DIR/get_default.rs:41:17 | LL | fn err(map: &mut Map) -> &String { | - let's call the lifetime of this reference `'1` @@ -41,8 +77,8 @@ LL | return v; | - returning this value requires that `*map` is borrowed for `'1` ... LL | map.set(String::new()); // Ideally, just AST would error here - | ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^ mutable borrow occurs here -error: aborting due to 3 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/nll/loan_ends_mid_block_pair.stderr b/src/test/ui/nll/loan_ends_mid_block_pair.stderr index eb8442b31d7c7..85703bda31c4e 100644 --- a/src/test/ui/nll/loan_ends_mid_block_pair.stderr +++ b/src/test/ui/nll/loan_ends_mid_block_pair.stderr @@ -1,5 +1,59 @@ -error[E0506]: cannot assign to `data.0` because it is borrowed - --> $DIR/loan_ends_mid_block_pair.rs:12:5 +error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) + --> $DIR/loan_ends_mid_block_pair.rs:14:5 + | +LL | let c = &mut data.0; + | ------ borrow of `data.0` occurs here +LL | capitalize(c); +LL | data.0 = 'e'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here + +error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) + --> $DIR/loan_ends_mid_block_pair.rs:17:5 + | +LL | let c = &mut data.0; + | ------ borrow of `data.0` occurs here +... +LL | data.0 = 'f'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here + +error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) + --> $DIR/loan_ends_mid_block_pair.rs:19:5 + | +LL | let c = &mut data.0; + | ------ borrow of `data.0` occurs here +... +LL | data.0 = 'g'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here + +error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) + --> $DIR/loan_ends_mid_block_pair.rs:28:5 + | +LL | let c = &mut data.0; + | ------ borrow of `data.0` occurs here +LL | capitalize(c); +LL | data.0 = 'e'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here + +error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) + --> $DIR/loan_ends_mid_block_pair.rs:30:5 + | +LL | let c = &mut data.0; + | ------ borrow of `data.0` occurs here +... +LL | data.0 = 'f'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here + +error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) + --> $DIR/loan_ends_mid_block_pair.rs:32:5 + | +LL | let c = &mut data.0; + | ------ borrow of `data.0` occurs here +... +LL | data.0 = 'g'; + | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here + +error[E0506]: cannot assign to `data.0` because it is borrowed (Mir) + --> $DIR/loan_ends_mid_block_pair.rs:14:5 | LL | let c = &mut data.0; | ----------- borrow of `data.0` occurs here @@ -10,6 +64,6 @@ LL | data.0 = 'e'; LL | capitalize(c); | - borrow later used here -error: aborting due to previous error +error: aborting due to 7 previous errors For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/loan_ends_mid_block_vec.stderr b/src/test/ui/nll/loan_ends_mid_block_vec.stderr index c0b97bea348c4..a3f1391f00140 100644 --- a/src/test/ui/nll/loan_ends_mid_block_vec.stderr +++ b/src/test/ui/nll/loan_ends_mid_block_vec.stderr @@ -1,5 +1,77 @@ -error[E0499]: cannot borrow `data` as mutable more than once at a time - --> $DIR/loan_ends_mid_block_vec.rs:11:5 +error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) + --> $DIR/loan_ends_mid_block_vec.rs:13:5 + | +LL | let slice = &mut data; + | ---- first mutable borrow occurs here +LL | capitalize(slice); +LL | data.push('d'); + | ^^^^ second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) + --> $DIR/loan_ends_mid_block_vec.rs:16:5 + | +LL | let slice = &mut data; + | ---- first mutable borrow occurs here +... +LL | data.push('e'); + | ^^^^ second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) + --> $DIR/loan_ends_mid_block_vec.rs:19:5 + | +LL | let slice = &mut data; + | ---- first mutable borrow occurs here +... +LL | data.push('f'); + | ^^^^ second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) + --> $DIR/loan_ends_mid_block_vec.rs:29:5 + | +LL | let slice = &mut data; + | ---- first mutable borrow occurs here +LL | capitalize(slice); +LL | data.push('d'); + | ^^^^ second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) + --> $DIR/loan_ends_mid_block_vec.rs:31:5 + | +LL | let slice = &mut data; + | ---- first mutable borrow occurs here +... +LL | data.push('e'); + | ^^^^ second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) + --> $DIR/loan_ends_mid_block_vec.rs:33:5 + | +LL | let slice = &mut data; + | ---- first mutable borrow occurs here +... +LL | data.push('f'); + | ^^^^ second mutable borrow occurs here +LL | +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `data` as mutable more than once at a time (Mir) + --> $DIR/loan_ends_mid_block_vec.rs:13:5 | LL | let slice = &mut data; | --------- first mutable borrow occurs here @@ -10,8 +82,8 @@ LL | data.push('d'); LL | capitalize(slice); | ----- first borrow later used here -error[E0499]: cannot borrow `data` as mutable more than once at a time - --> $DIR/loan_ends_mid_block_vec.rs:13:5 +error[E0499]: cannot borrow `data` as mutable more than once at a time (Mir) + --> $DIR/loan_ends_mid_block_vec.rs:16:5 | LL | let slice = &mut data; | --------- first mutable borrow occurs here @@ -22,18 +94,18 @@ LL | data.push('e'); LL | capitalize(slice); | ----- first borrow later used here -error[E0499]: cannot borrow `data` as mutable more than once at a time - --> $DIR/loan_ends_mid_block_vec.rs:15:5 +error[E0499]: cannot borrow `data` as mutable more than once at a time (Mir) + --> $DIR/loan_ends_mid_block_vec.rs:19:5 | LL | let slice = &mut data; | --------- first mutable borrow occurs here ... LL | data.push('f'); | ^^^^ second mutable borrow occurs here -LL | +... LL | capitalize(slice); | ----- first borrow later used here -error: aborting due to 3 previous errors +error: aborting due to 9 previous errors For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/nll/region-ends-after-if-condition.stderr b/src/test/ui/nll/region-ends-after-if-condition.stderr index c03e385790616..aa876a0bcb3bf 100644 --- a/src/test/ui/nll/region-ends-after-if-condition.stderr +++ b/src/test/ui/nll/region-ends-after-if-condition.stderr @@ -1,15 +1,39 @@ -error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable - --> $DIR/region-ends-after-if-condition.rs:26:9 +error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable (Ast) + --> $DIR/region-ends-after-if-condition.rs:19:9 + | +LL | let value = &my_struct.field; + | --------------- immutable borrow occurs here +LL | if value.is_empty() { +LL | my_struct.field.push_str("Hello, world!"); + | ^^^^^^^^^^^^^^^ mutable borrow occurs here +... +LL | } + | - immutable borrow ends here + +error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable (Ast) + --> $DIR/region-ends-after-if-condition.rs:29:9 + | +LL | let value = &my_struct.field; + | --------------- immutable borrow occurs here +LL | if value.is_empty() { +LL | my_struct.field.push_str("Hello, world!"); + | ^^^^^^^^^^^^^^^ mutable borrow occurs here +... +LL | } + | - immutable borrow ends here + +error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable (Mir) + --> $DIR/region-ends-after-if-condition.rs:29:9 | LL | let value = &my_struct.field; | ---------------- immutable borrow occurs here LL | if value.is_empty() { LL | my_struct.field.push_str("Hello, world!"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^^^^^^^^^^^^^ mutable borrow occurs here ... LL | drop(value); | ----- immutable borrow later used here -error: aborting due to previous error +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/nll/return_from_loop.stderr b/src/test/ui/nll/return_from_loop.stderr index efd56ea2dd542..09882d55cb70e 100644 --- a/src/test/ui/nll/return_from_loop.stderr +++ b/src/test/ui/nll/return_from_loop.stderr @@ -1,15 +1,39 @@ -error[E0499]: cannot borrow `my_struct.field` as mutable more than once at a time - --> $DIR/return_from_loop.rs:20:9 +error[E0499]: cannot borrow `my_struct.field` as mutable more than once at a time (Ast) + --> $DIR/return_from_loop.rs:22:9 + | +LL | let value = &mut my_struct.field; + | --------------- first mutable borrow occurs here +LL | loop { +LL | my_struct.field.push_str("Hello, world!"); + | ^^^^^^^^^^^^^^^ second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `my_struct.field` as mutable more than once at a time (Ast) + --> $DIR/return_from_loop.rs:35:9 + | +LL | let value = &mut my_struct.field; + | --------------- first mutable borrow occurs here +LL | loop { +LL | my_struct.field.push_str("Hello, world!"); + | ^^^^^^^^^^^^^^^ second mutable borrow occurs here +... +LL | } + | - first borrow ends here + +error[E0499]: cannot borrow `my_struct.field` as mutable more than once at a time (Mir) + --> $DIR/return_from_loop.rs:22:9 | LL | let value = &mut my_struct.field; | -------------------- first mutable borrow occurs here LL | loop { LL | my_struct.field.push_str("Hello, world!"); | ^^^^^^^^^^^^^^^ second mutable borrow occurs here -LL | +... LL | value.len(); | ----- first borrow later used here -error: aborting due to previous error +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/numeric/const-scope.stderr b/src/test/ui/numeric/const-scope.stderr index 3f69bcc7d4a2f..ead3a79da0270 100644 --- a/src/test/ui/numeric/const-scope.stderr +++ b/src/test/ui/numeric/const-scope.stderr @@ -37,7 +37,7 @@ error[E0308]: mismatched types | LL | let d: i8 = c; | ^ expected i8, found i32 -help: you can convert an `i32` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `i8` or panic if it the converted value wouldn't fit | LL | let d: i8 = c.try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/numeric/len.stderr b/src/test/ui/numeric/len.stderr index c767bdd9bd5a5..5a9349b4c0f29 100644 --- a/src/test/ui/numeric/len.stderr +++ b/src/test/ui/numeric/len.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | test(array.len()); | ^^^^^^^^^^^ expected u32, found usize -help: you can convert an `usize` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `u32` or panic if it the converted value wouldn't fit | LL | test(array.len().try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/numeric/numeric-cast-2.stderr b/src/test/ui/numeric/numeric-cast-2.stderr index f58389ce96c3b..be4411e630bec 100644 --- a/src/test/ui/numeric/numeric-cast-2.stderr +++ b/src/test/ui/numeric/numeric-cast-2.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | let x: u16 = foo(); | ^^^^^ expected u16, found i32 -help: you can convert an `i32` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `u16` or panic if it the converted value wouldn't fit | LL | let x: u16 = foo().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ error[E0308]: mismatched types | LL | let y: i64 = x + x; | ^^^^^ expected i64, found u16 -help: you can convert an `u16` to `i64` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `i64` or panic if it the converted value wouldn't fit | LL | let y: i64 = (x + x).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ error[E0308]: mismatched types | LL | let z: i32 = x + x; | ^^^^^ expected i32, found u16 -help: you can convert an `u16` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `i32` or panic if it the converted value wouldn't fit | LL | let z: i32 = (x + x).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/numeric/numeric-cast.stderr b/src/test/ui/numeric/numeric-cast.stderr index e66b83f2b39f5..9e7dcf7e41b55 100644 --- a/src/test/ui/numeric/numeric-cast.stderr +++ b/src/test/ui/numeric/numeric-cast.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected usize, found u64 -help: you can convert an `u64` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `usize` or panic if it the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected usize, found u32 -help: you can convert an `u32` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `usize` or panic if it the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected usize, found u16 -help: you can convert an `u16` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `usize` or panic if it the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected usize, found u8 -help: you can convert an `u8` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `u8` to `usize` or panic if it the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected usize, found isize -help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `usize` or panic if it the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected usize, found i64 -help: you can convert an `i64` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `usize` or panic if it the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -63,7 +63,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected usize, found i32 -help: you can convert an `i32` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `usize` or panic if it the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected usize, found i16 -help: you can convert an `i16` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `i16` to `usize` or panic if it the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected usize, found i8 -help: you can convert an `i8` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `i8` to `usize` or panic if it the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,7 +93,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected isize, found usize -help: you can convert an `usize` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `isize` or panic if it the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -103,7 +103,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected isize, found u64 -help: you can convert an `u64` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `isize` or panic if it the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected isize, found u32 -help: you can convert an `u32` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `isize` or panic if it the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected isize, found u16 -help: you can convert an `u16` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `isize` or panic if it the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected isize, found u8 -help: you can convert an `u8` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `u8` to `isize` or panic if it the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -143,7 +143,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected isize, found i64 -help: you can convert an `i64` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `isize` or panic if it the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -153,7 +153,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected isize, found i32 -help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `isize` or panic if it the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected isize, found i16 -help: you can convert an `i16` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `i16` to `isize` or panic if it the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -173,7 +173,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected isize, found i8 -help: you can convert an `i8` to `isize` and panic if the converted value wouldn't fit +help: you can convert an `i8` to `isize` or panic if it the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +183,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected u64, found usize -help: you can convert an `usize` to `u64` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `u64` or panic if it the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected u64, found isize -help: you can convert an `isize` to `u64` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `u64` or panic if it the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -230,7 +230,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected u64, found i64 -help: you can convert an `i64` to `u64` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `u64` or panic if it the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -240,7 +240,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected u64, found i32 -help: you can convert an `i32` to `u64` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `u64` or panic if it the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -250,7 +250,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected u64, found i16 -help: you can convert an `i16` to `u64` and panic if the converted value wouldn't fit +help: you can convert an `i16` to `u64` or panic if it the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -260,7 +260,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected u64, found i8 -help: you can convert an `i8` to `u64` and panic if the converted value wouldn't fit +help: you can convert an `i8` to `u64` or panic if it the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -270,7 +270,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected i64, found usize -help: you can convert an `usize` to `i64` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `i64` or panic if it the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -280,7 +280,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected i64, found u64 -help: you can convert an `u64` to `i64` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `i64` or panic if it the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -290,7 +290,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected i64, found u32 -help: you can convert an `u32` to `i64` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `i64` or panic if it the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -300,7 +300,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected i64, found u16 -help: you can convert an `u16` to `i64` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `i64` or panic if it the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -310,7 +310,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected i64, found u8 -help: you can convert an `u8` to `i64` and panic if the converted value wouldn't fit +help: you can convert an `u8` to `i64` or panic if it the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -320,7 +320,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected i64, found isize -help: you can convert an `isize` to `i64` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `i64` or panic if it the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected u32, found usize -help: you can convert an `usize` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `u32` or panic if it the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -367,7 +367,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected u32, found u64 -help: you can convert an `u64` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `u32` or panic if it the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -395,7 +395,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected u32, found isize -help: you can convert an `isize` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `u32` or panic if it the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -405,7 +405,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected u32, found i64 -help: you can convert an `i64` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `u32` or panic if it the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -415,7 +415,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected u32, found i32 -help: you can convert an `i32` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `u32` or panic if it the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -425,7 +425,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected u32, found i16 -help: you can convert an `i16` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `i16` to `u32` or panic if it the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -435,7 +435,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected u32, found i8 -help: you can convert an `i8` to `u32` and panic if the converted value wouldn't fit +help: you can convert an `i8` to `u32` or panic if it the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -445,7 +445,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected i32, found usize -help: you can convert an `usize` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `i32` or panic if it the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -455,7 +455,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected i32, found u64 -help: you can convert an `u64` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `i32` or panic if it the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -465,7 +465,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected i32, found u32 -help: you can convert an `u32` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `i32` or panic if it the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -475,7 +475,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected i32, found u16 -help: you can convert an `u16` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `i32` or panic if it the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -485,7 +485,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected i32, found u8 -help: you can convert an `u8` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `u8` to `i32` or panic if it the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -495,7 +495,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected i32, found isize -help: you can convert an `isize` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `i32` or panic if it the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -505,7 +505,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected i32, found i64 -help: you can convert an `i64` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i32` or panic if it the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -533,7 +533,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected u16, found usize -help: you can convert an `usize` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `u16` or panic if it the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -543,7 +543,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected u16, found u64 -help: you can convert an `u64` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `u16` or panic if it the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -553,7 +553,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected u16, found u32 -help: you can convert an `u32` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `u16` or panic if it the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -572,7 +572,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected u16, found isize -help: you can convert an `isize` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `u16` or panic if it the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -582,7 +582,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected u16, found i64 -help: you can convert an `i64` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `u16` or panic if it the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -592,7 +592,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected u16, found i32 -help: you can convert an `i32` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `u16` or panic if it the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -602,7 +602,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected u16, found i16 -help: you can convert an `i16` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `i16` to `u16` or panic if it the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -612,7 +612,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected u16, found i8 -help: you can convert an `i8` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `i8` to `u16` or panic if it the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -622,7 +622,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected i16, found usize -help: you can convert an `usize` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `i16` or panic if it the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -632,7 +632,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected i16, found u64 -help: you can convert an `u64` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `i16` or panic if it the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -642,7 +642,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected i16, found u32 -help: you can convert an `u32` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `i16` or panic if it the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -652,7 +652,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected i16, found u16 -help: you can convert an `u16` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `i16` or panic if it the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -662,7 +662,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected i16, found u8 -help: you can convert an `u8` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `u8` to `i16` or panic if it the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -672,7 +672,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected i16, found isize -help: you can convert an `isize` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `i16` or panic if it the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -682,7 +682,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected i16, found i64 -help: you can convert an `i64` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i16` or panic if it the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -692,7 +692,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected i16, found i32 -help: you can convert an `i32` to `i16` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `i16` or panic if it the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -711,7 +711,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected u8, found usize -help: you can convert an `usize` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `u8` or panic if it the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -721,7 +721,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected u8, found u64 -help: you can convert an `u64` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `u8` or panic if it the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -731,7 +731,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected u8, found u32 -help: you can convert an `u32` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `u8` or panic if it the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -741,7 +741,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected u8, found u16 -help: you can convert an `u16` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `u8` or panic if it the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -751,7 +751,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected u8, found isize -help: you can convert an `isize` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `u8` or panic if it the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -761,7 +761,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected u8, found i64 -help: you can convert an `i64` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `u8` or panic if it the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -771,7 +771,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected u8, found i32 -help: you can convert an `i32` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `u8` or panic if it the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -781,7 +781,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected u8, found i16 -help: you can convert an `i16` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `i16` to `u8` or panic if it the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -791,7 +791,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected u8, found i8 -help: you can convert an `i8` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `i8` to `u8` or panic if it the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -801,7 +801,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected i8, found usize -help: you can convert an `usize` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `usize` to `i8` or panic if it the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -811,7 +811,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected i8, found u64 -help: you can convert an `u64` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `u64` to `i8` or panic if it the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -821,7 +821,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected i8, found u32 -help: you can convert an `u32` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `u32` to `i8` or panic if it the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -831,7 +831,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected i8, found u16 -help: you can convert an `u16` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `u16` to `i8` or panic if it the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -841,7 +841,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected i8, found u8 -help: you can convert an `u8` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `u8` to `i8` or panic if it the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -851,7 +851,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected i8, found isize -help: you can convert an `isize` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `i8` or panic if it the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -861,7 +861,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected i8, found i64 -help: you can convert an `i64` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i8` or panic if it the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -871,7 +871,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected i8, found i32 -help: you can convert an `i32` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `i8` or panic if it the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -881,7 +881,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected i8, found i16 -help: you can convert an `i16` to `i8` and panic if the converted value wouldn't fit +help: you can convert an `i16` to `i8` or panic if it the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/pub/pub-restricted.stderr b/src/test/ui/pub/pub-restricted.stderr index 596264ba16b42..7eeefa9550543 100644 --- a/src/test/ui/pub/pub-restricted.stderr +++ b/src/test/ui/pub/pub-restricted.stderr @@ -21,18 +21,7 @@ LL | pub (b) fn bfn() {} `pub(in path::to::module)`: visible only on the specified path error[E0704]: incorrect visibility restriction - --> $DIR/pub-restricted.rs:7:6 - | -LL | pub (crate::a) fn cfn() {} - | ^^^^^^^^ help: make this visible only to module `crate::a` with `in`: `in crate::a` - | - = help: some possible visibility restrictions are: - `pub(crate)`: visible only on the current crate - `pub(super)`: visible only in the current module's parent - `pub(in path::to::module)`: visible only on the specified path - -error[E0704]: incorrect visibility restriction - --> $DIR/pub-restricted.rs:24:14 + --> $DIR/pub-restricted.rs:22:14 | LL | pub (a) invalid: usize, | ^ help: make this visible only to module `a` with `in`: `in a` @@ -43,7 +32,7 @@ LL | pub (a) invalid: usize, `pub(in path::to::module)`: visible only on the specified path error[E0704]: incorrect visibility restriction - --> $DIR/pub-restricted.rs:33:6 + --> $DIR/pub-restricted.rs:31:6 | LL | pub (xyz) fn xyz() {} | ^^^ help: make this visible only to module `xyz` with `in`: `in xyz` @@ -54,11 +43,11 @@ LL | pub (xyz) fn xyz() {} `pub(in path::to::module)`: visible only on the specified path error: visibilities can only be restricted to ancestor modules - --> $DIR/pub-restricted.rs:25:17 + --> $DIR/pub-restricted.rs:23:17 | LL | pub (in x) non_parent_invalid: usize, | ^ -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0704`. diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index df73ac0b182f0..6772aa1c38d2c 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -42,7 +42,7 @@ error[E0308]: mismatched types | LL | let f = [0; -4_isize]; | ^^^^^^^^ expected usize, found isize -help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `usize` or panic if it the converted value wouldn't fit | LL | let f = [0; (-4_isize).try_into().unwrap()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ error[E0308]: mismatched types | LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected usize, found isize -help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `usize` or panic if it the converted value wouldn't fit | LL | let f = [0_usize; (-1_isize).try_into().unwrap()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/shift-various-bad-types.stderr b/src/test/ui/shift-various-bad-types.stderr index 409fabb951adc..97523fe82cd4e 100644 --- a/src/test/ui/shift-various-bad-types.stderr +++ b/src/test/ui/shift-various-bad-types.stderr @@ -27,7 +27,7 @@ error[E0308]: mismatched types | LL | let _: i32 = 22_i64 >> 1_i32; | ^^^^^^^^^^^^^^^ expected i32, found i64 -help: you can convert an `i64` to `i32` and panic if the converted value wouldn't fit +help: you can convert an `i64` to `i32` or panic if it the converted value wouldn't fit | LL | let _: i32 = (22_i64 >> 1_i32).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/basic.stderr b/src/test/ui/symbol-names/basic.stderr new file mode 100644 index 0000000000000..6ddd93d632e15 --- /dev/null +++ b/src/test/ui/symbol-names/basic.stderr @@ -0,0 +1,14 @@ +error: symbol-name(_ZN5basic4main17h08bcaf310214ed52E) + --> $DIR/basic.rs:3:1 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: def-path(main) + --> $DIR/basic.rs:4:1 + | +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/symbol-names/impl1.stderr b/src/test/ui/symbol-names/impl1.stderr new file mode 100644 index 0000000000000..eda8646b5b4de --- /dev/null +++ b/src/test/ui/symbol-names/impl1.stderr @@ -0,0 +1,26 @@ +error: symbol-name(_ZN5impl13foo3Foo3bar17hc487d6ec13fe9124E) + --> $DIR/impl1.rs:8:9 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: def-path(foo::Foo::bar) + --> $DIR/impl1.rs:9:9 + | +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ + +error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h38577281258e1527E) + --> $DIR/impl1.rs:18:9 + | +LL | #[rustc_symbol_name] + | ^^^^^^^^^^^^^^^^^^^^ + +error: def-path(bar::::baz) + --> $DIR/impl1.rs:19:9 + | +LL | #[rustc_def_path] + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 4 previous errors + diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr index e9c28248044f9..9acd63c2c25f1 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr @@ -6,7 +6,7 @@ LL | fn global_bound_is_hidden() -> u8 ... LL | B::get_x() | ^^^^^^^^^^ expected u8, found i32 -help: you can convert an `i32` to `u8` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `u8` or panic if it the converted value wouldn't fit | LL | B::get_x().try_into().unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/tutorial-suffix-inference-test.stderr b/src/test/ui/tutorial-suffix-inference-test.stderr index f3e1cc41cada2..f51f2defd4759 100644 --- a/src/test/ui/tutorial-suffix-inference-test.stderr +++ b/src/test/ui/tutorial-suffix-inference-test.stderr @@ -12,7 +12,7 @@ error[E0308]: mismatched types | LL | identity_u16(y); | ^ expected u16, found i32 -help: you can convert an `i32` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `i32` to `u16` or panic if it the converted value wouldn't fit | LL | identity_u16(y.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ error[E0308]: mismatched types | LL | identity_u16(a); | ^ expected u16, found isize -help: you can convert an `isize` to `u16` and panic if the converted value wouldn't fit +help: you can convert an `isize` to `u16` or panic if it the converted value wouldn't fit | LL | identity_u16(a.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^ From 0f4a5ca33ceb22edd4f2cd12a03806331a2883ed Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 8 May 2019 15:56:39 -0400 Subject: [PATCH 09/24] Added some comments to lowering code. --- src/librustc/hir/lowering.rs | 53 ++++++++++++++++++++++++++++++++++-- 1 file changed, 50 insertions(+), 3 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index a49744aa523a9..06f9128cd2263 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1361,26 +1361,73 @@ impl<'a> LoweringContext<'a> { } } + /// Given an associated type constraint like one of these: + /// + /// ``` + /// T: Iterator + /// ^^^^^^^^^^^ + /// T: Iterator + /// ^^^^^^^^^^^^ + /// ``` + /// + /// returns a `hir::TypeBinding` representing `Item`. fn lower_assoc_ty_constraint(&mut self, c: &AssocTyConstraint, itctx: ImplTraitContext<'_>) -> hir::TypeBinding { debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", c, itctx); + // Convert to a type representing the `T::Item` value. let ty = match c.kind { AssocTyConstraintKind::Equality { ref ty } => self.lower_ty(ty, itctx), AssocTyConstraintKind::Bound { ref bounds } => { - let (existential_desugaring, itctx) = match itctx { + // Piggy-back on the impl trait context to figure out + // the correct behavior. + let (desugar_to_impl_trait, itctx) = match itctx { + // We are in the return position: + // + // fn foo() -> impl Iterator + // + // so desugar to + // + // fn foo() -> impl Iterator ImplTraitContext::Existential(_) => (true, itctx), + + // We are in the argument position, but within a dyn type: + // + // fn foo(x: dyn Iterator) + // + // so desugar to + // + // fn foo(x: dyn Iterator) ImplTraitContext::Universal(_) if self.is_in_dyn_type => (true, itctx), + + // In `type Foo = dyn Iterator` we + // desugar to `type Foo = dyn Iterator` but we have to override the "impl trait + // context" to permit `impl Debug` in this + // position (it desugars then to an existential + // type). + // // FIXME: this is only needed until `impl Trait` is allowed in type aliases. ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => (true, ImplTraitContext::Existential(None)), + + // We are in the argument position, but not within a dyn type: + // + // fn foo(x: impl Iterator) + // + // so we leave it as is and this gets expanded in + // astconv to a bound like `::Item: + // Debug` where `T` is the type parameter for the + // `impl Iterator`. _ => (false, itctx), }; - if existential_desugaring { - // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. + if desugar_to_impl_trait { + // Desugar `AssocTy: Bounds` into `AssocTy = impl + // Bounds`. We do this by constructing the HIR + // for "impl bounds" and then lowering that. let impl_trait_node_id = self.sess.next_node_id(); let parent_def_index = self.current_hir_id_owner.last().unwrap().0; From 538ebd197c52f2551f550d7aa5c82f7b3412c99d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 8 May 2019 15:58:20 -0400 Subject: [PATCH 10/24] Added some comments, made `add_bounds` private. --- src/librustc_typeck/astconv.rs | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index e37ad77b086fd..fe17d902c617c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -699,6 +699,15 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }, ); + // Convert associated-type bindings or constraints into a separate vector. + // Example: Given this: + // + // T: Iterator + // + // The `T` is passed in as a self-type; the `Item = u32` is + // not a "type parameter" of the `Iterator` trait, but rather + // a restriction on `::Item`, so it is passed + // back separately. let assoc_bindings = generic_args.bindings.iter() .map(|binding| { let kind = if let hir::TyKind::AssocTyExistential(ref bounds) = binding.ty.node { @@ -899,7 +908,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { true } - pub fn add_bounds(&self, + fn add_bounds(&self, param_ty: Ty<'tcx>, ast_bounds: &[hir::GenericBound], bounds: &mut Bounds<'tcx>, @@ -1065,6 +1074,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { match binding.kind { ConvertedBindingKind::Equality(ref ty) => { + // "Desugar" a constraint like `T: Iterator` this to + // the "projection predicate" for: + // + // `::Item = u32` bounds.projection_bounds.push((candidate.map_bound(|trait_ref| { ty::ProjectionPredicate { projection_ty: ty::ProjectionTy::from_ref_and_name( From 5bf5994d922744c1d9e44b53a6ad54005fe3489e Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Fri, 10 May 2019 03:46:39 +0100 Subject: [PATCH 11/24] Fixed up some comments. --- src/librustc/hir/lowering.rs | 33 ++++++++++++++------------------- 1 file changed, 14 insertions(+), 19 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 06f9128cd2263..4c96e106d1f1b 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1381,33 +1381,30 @@ impl<'a> LoweringContext<'a> { let ty = match c.kind { AssocTyConstraintKind::Equality { ref ty } => self.lower_ty(ty, itctx), AssocTyConstraintKind::Bound { ref bounds } => { - // Piggy-back on the impl trait context to figure out - // the correct behavior. + // Piggy-back on the `impl Trait` context to figure out the correct behavior. let (desugar_to_impl_trait, itctx) = match itctx { // We are in the return position: // - // fn foo() -> impl Iterator + // fn foo() -> impl Iterator // // so desugar to // - // fn foo() -> impl Iterator + // fn foo() -> impl Iterator ImplTraitContext::Existential(_) => (true, itctx), // We are in the argument position, but within a dyn type: // - // fn foo(x: dyn Iterator) + // fn foo(x: dyn Iterator) // // so desugar to // - // fn foo(x: dyn Iterator) + // fn foo(x: dyn Iterator) ImplTraitContext::Universal(_) if self.is_in_dyn_type => (true, itctx), - // In `type Foo = dyn Iterator` we - // desugar to `type Foo = dyn Iterator` but we have to override the "impl trait - // context" to permit `impl Debug` in this - // position (it desugars then to an existential - // type). + // In `type Foo = dyn Iterator` we desugar to + // `type Foo = dyn Iterator` but we have to override the + // "impl trait context" to permit `impl Debug` in this position (it desugars + // then to an existential type). // // FIXME: this is only needed until `impl Trait` is allowed in type aliases. ImplTraitContext::Disallowed(_) if self.is_in_dyn_type => @@ -1415,19 +1412,17 @@ impl<'a> LoweringContext<'a> { // We are in the argument position, but not within a dyn type: // - // fn foo(x: impl Iterator) + // fn foo(x: impl Iterator) // - // so we leave it as is and this gets expanded in - // astconv to a bound like `::Item: - // Debug` where `T` is the type parameter for the + // so we leave it as is and this gets expanded in astconv to a bound like + // `::Item: Debug` where `T` is the type parameter for the // `impl Iterator`. _ => (false, itctx), }; if desugar_to_impl_trait { - // Desugar `AssocTy: Bounds` into `AssocTy = impl - // Bounds`. We do this by constructing the HIR - // for "impl bounds" and then lowering that. + // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by + // constructing the HIR for "impl bounds" and then lowering that. let impl_trait_node_id = self.sess.next_node_id(); let parent_def_index = self.current_hir_id_owner.last().unwrap().0; From f472cd9c02e77654ba6ba324c0b4b15aefa96f48 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 8 May 2019 15:57:06 -0400 Subject: [PATCH 12/24] Addressed points raised in review. --- src/librustc/hir/intravisit.rs | 12 +++-- src/librustc/hir/lowering.rs | 52 +++++++++++++--------- src/librustc/hir/mod.rs | 53 +++++++++++++++++----- src/librustc/hir/print.rs | 16 ++++--- src/librustc/middle/resolve_lifetime.rs | 6 +-- src/librustc_typeck/astconv.rs | 13 +++--- src/librustdoc/clean/auto_trait.rs | 4 +- src/librustdoc/clean/mod.rs | 58 ++++++++++++++++++++----- src/librustdoc/clean/simplify.rs | 4 +- src/librustdoc/html/format.rs | 23 ++++++++-- 10 files changed, 172 insertions(+), 69 deletions(-) diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index da4d41c9d872f..1c66f8bdf81bd 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -626,9 +626,6 @@ pub fn walk_ty<'v, V: Visitor<'v>>(visitor: &mut V, typ: &'v Ty) { TyKind::CVarArgs(ref lt) => { visitor.visit_lifetime(lt) } - TyKind::AssocTyExistential(ref bounds) => { - walk_list!(visitor, visit_param_bound, bounds); - } TyKind::Infer | TyKind::Err => {} } } @@ -677,7 +674,14 @@ pub fn walk_assoc_type_binding<'v, V: Visitor<'v>>(visitor: &mut V, type_binding: &'v TypeBinding) { visitor.visit_id(type_binding.hir_id); visitor.visit_ident(type_binding.ident); - visitor.visit_ty(&type_binding.ty); + match type_binding.kind { + TypeBindingKind::Equality { ref ty } => { + visitor.visit_ty(ty); + } + TypeBindingKind::Constraint { ref bounds } => { + walk_list!(visitor, visit_param_bound, bounds); + } + } } pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 4c96e106d1f1b..1bfff138d8dca 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1377,9 +1377,10 @@ impl<'a> LoweringContext<'a> { -> hir::TypeBinding { debug!("lower_assoc_ty_constraint(constraint={:?}, itctx={:?})", c, itctx); - // Convert to a type representing the `T::Item` value. - let ty = match c.kind { - AssocTyConstraintKind::Equality { ref ty } => self.lower_ty(ty, itctx), + let kind = match c.kind { + AssocTyConstraintKind::Equality { ref ty } => hir::TypeBindingKind::Equality { + ty: self.lower_ty(ty, itctx) + }, AssocTyConstraintKind::Bound { ref bounds } => { // Piggy-back on the `impl Trait` context to figure out the correct behavior. let (desugar_to_impl_trait, itctx) = match itctx { @@ -1422,7 +1423,7 @@ impl<'a> LoweringContext<'a> { if desugar_to_impl_trait { // Desugar `AssocTy: Bounds` into `AssocTy = impl Bounds`. We do this by - // constructing the HIR for "impl bounds" and then lowering that. + // constructing the HIR for `impl bounds...` and then lowering that. let impl_trait_node_id = self.sess.next_node_id(); let parent_def_index = self.current_hir_id_owner.last().unwrap().0; @@ -1436,27 +1437,27 @@ impl<'a> LoweringContext<'a> { ); self.with_dyn_type_scope(false, |this| { - this.lower_ty( + let ty = this.lower_ty( &Ty { id: this.sess.next_node_id(), node: TyKind::ImplTrait(impl_trait_node_id, bounds.clone()), span: DUMMY_SP, }, itctx, - ) + ); + + hir::TypeBindingKind::Equality { + ty + } }) } else { - // Desugar `AssocTy: Bounds` into `AssocTy = ∃ T (T: Bounds)`, where the - // "false existential" later desugars into a trait predicate. - + // Desugar `AssocTy: Bounds` into a type binding where the + // later desugars into a trait predicate. let bounds = self.lower_param_bounds(bounds, itctx); - let id = self.sess.next_node_id(); - P(hir::Ty { - hir_id: self.lower_node_id(id), - node: hir::TyKind::AssocTyExistential(bounds), - span: DUMMY_SP, - }) + hir::TypeBindingKind::Constraint { + bounds + } } } }; @@ -1464,7 +1465,7 @@ impl<'a> LoweringContext<'a> { hir::TypeBinding { hir_id: self.lower_node_id(c.id), ident: c.ident, - ty, + kind, span: c.span, } } @@ -2359,10 +2360,17 @@ impl<'a> LoweringContext<'a> { hir::TypeBinding { hir_id: this.next_id(), ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME), - ty: output - .as_ref() - .map(|ty| this.lower_ty(&ty, ImplTraitContext::disallowed())) - .unwrap_or_else(|| P(mk_tup(this, hir::HirVec::new(), span))), + kind: hir::TypeBindingKind::Equality { + ty: output + .as_ref() + .map(|ty| this.lower_ty( + &ty, + ImplTraitContext::disallowed() + )) + .unwrap_or_else(|| + P(mk_tup(this, hir::HirVec::new(), span)) + ), + }, span: output.as_ref().map_or(span, |ty| ty.span), } ], @@ -2666,7 +2674,9 @@ impl<'a> LoweringContext<'a> { args: hir_vec![], bindings: hir_vec![hir::TypeBinding { ident: Ident::with_empty_ctxt(FN_OUTPUT_NAME), - ty: output_ty, + kind: hir::TypeBindingKind::Equality { + ty: output_ty, + }, hir_id: self.next_id(), span, }], diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index f884651e8be32..2aaf5ec775d49 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -1780,7 +1780,7 @@ pub struct ImplItem { pub span: Span, } -/// Represents different contents within `impl`s. +/// Represents various kinds of content within an `impl`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum ImplItemKind { /// An associated constant of the given type, set to the constant result @@ -1794,16 +1794,51 @@ pub enum ImplItemKind { Existential(GenericBounds), } -// Bind a type to an associated type (`A = Foo`). +/// Bind a type to an associated type (i.e., `A = Foo`). +/// +/// Bindings like `A: Debug` are represented as a special type `A = +/// $::Debug` that is understood by the astconv code. +/// +/// FIXME(alexreg) -- why have a separate type for the binding case, +/// wouldn't it be better to make the `ty` field an enum like: +/// +/// ``` +/// enum TypeBindingKind { +/// Equals(...), +/// Binding(...), +/// } +/// ``` #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub struct TypeBinding { pub hir_id: HirId, #[stable_hasher(project(name))] pub ident: Ident, - pub ty: P, + pub kind: TypeBindingKind, pub span: Span, } +// Represents the two kinds of type bindings. +#[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] +pub enum TypeBindingKind { + /// E.g., `Foo`. + Constraint { + bounds: HirVec, + }, + /// E.g., `Foo`. + Equality { + ty: P, + }, +} + +impl TypeBinding { + pub fn ty(&self) -> &Ty { + match self.kind { + TypeBindingKind::Equality { ref ty } => ty, + _ => bug!("expected equality type binding for parenthesized generic args"), + } + } +} + #[derive(Clone, RustcEncodable, RustcDecodable)] pub struct Ty { pub hir_id: HirId, @@ -1898,8 +1933,6 @@ pub enum TyKind { /// Placeholder for C-variadic arguments. We "spoof" the `VaList` created /// from the variadic arguments. This type is only valid up to typeck. CVarArgs(Lifetime), - /// The existential type (i.e., `impl Trait`) that constrains an associated type. - AssocTyExistential(HirVec), } #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] @@ -2236,18 +2269,18 @@ impl StructField { } } -/// Fields and constructor ids of enum variants and structs +/// Fields and constructor IDs of enum variants and structs. #[derive(Clone, RustcEncodable, RustcDecodable, Debug, HashStable)] pub enum VariantData { - /// Struct variant. + /// A struct variant. /// - /// e.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`. + /// E.g., `Bar { .. }` as in `enum Foo { Bar { .. } }`. Struct(HirVec, /* recovered */ bool), - /// Tuple variant. + /// A tuple variant. /// /// E.g., `Bar(..)` as in `enum Foo { Bar(..) }`. Tuple(HirVec, HirId), - /// Unit variant. + /// A unit variant. /// /// E.g., `Bar = ..` as in `enum Foo { Bar = .. }`. Unit(HirId), diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index c8f9e4c7043e0..c8615f0ed1b93 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -409,9 +409,6 @@ impl<'a> State<'a> { hir::TyKind::CVarArgs(_) => { self.s.word("...")?; } - hir::TyKind::AssocTyExistential(ref bounds) => { - self.print_bounds(":", bounds)?; - } } self.end() } @@ -1648,7 +1645,7 @@ impl<'a> State<'a> { self.space_if_not_bol()?; self.word_space("->")?; - self.print_type(&generic_args.bindings[0].ty)?; + self.print_type(generic_args.bindings[0].ty())?; } else { let start = if colons_before_params { "::<" } else { "<" }; let empty = Cell::new(true); @@ -1693,8 +1690,15 @@ impl<'a> State<'a> { start_or_comma(self)?; self.print_ident(binding.ident)?; self.s.space()?; - self.word_space("=")?; - self.print_type(&binding.ty)?; + match generic_args.bindings[0].kind { + hir::TypeBindingKind::Equality { ref ty } => { + self.word_space("=")?; + self.print_type(ty)?; + } + hir::TypeBindingKind::Constraint { ref bounds } => { + self.print_bounds(":", bounds)?; + } + } } if !empty.get() { diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 2e56ca6f56352..331b74db080bf 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -923,7 +923,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl) { let output = match fd.output { hir::DefaultReturn(_) => None, - hir::Return(ref ty) => Some(ty), + hir::Return(ref ty) => Some(&**ty), }; self.visit_fn_like_elision(&fd.inputs, output); } @@ -1884,7 +1884,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { if generic_args.parenthesized { let was_in_fn_syntax = self.is_in_fn_syntax; self.is_in_fn_syntax = true; - self.visit_fn_like_elision(generic_args.inputs(), Some(&generic_args.bindings[0].ty)); + self.visit_fn_like_elision(generic_args.inputs(), Some(generic_args.bindings[0].ty())); self.is_in_fn_syntax = was_in_fn_syntax; return; } @@ -2020,7 +2020,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } - fn visit_fn_like_elision(&mut self, inputs: &'tcx [hir::Ty], output: Option<&'tcx P>) { + fn visit_fn_like_elision(&mut self, inputs: &'tcx [hir::Ty], output: Option<&'tcx hir::Ty>) { debug!("visit_fn_like_elision: enter"); let mut arg_elide = Elide::FreshLateAnon(Cell::new(0)); let arg_scope = Scope::Elision { diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index fe17d902c617c..4a2949fa6b069 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -710,10 +710,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // back separately. let assoc_bindings = generic_args.bindings.iter() .map(|binding| { - let kind = if let hir::TyKind::AssocTyExistential(ref bounds) = binding.ty.node { - ConvertedBindingKind::Constraint(bounds.clone()) - } else { - ConvertedBindingKind::Equality(self.ast_ty_to_ty(&binding.ty)) + let kind = match binding.kind { + hir::TypeBindingKind::Equality { ref ty } => + ConvertedBindingKind::Equality(self.ast_ty_to_ty(ty)), + hir::TypeBindingKind::Constraint { ref bounds } => + ConvertedBindingKind::Constraint(bounds.clone()), }; ConvertedBinding { item_name: binding.ident, @@ -2060,10 +2061,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let region = self.ast_region_to_region(<, None); tcx.type_of(va_list_did).subst(tcx, &[region.into()]) } - hir::TyKind::AssocTyExistential(..) => { - // Type is never actually used. - tcx.types.err - } hir::TyKind::Err => { tcx.types.err } diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 8e2460a14b87a..60d6c33f81afc 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -626,7 +626,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> { } => { bindings.push(TypeBinding { name: left_name.clone(), - ty: rhs, + kind: TypeBindingKind::Equality { + ty: rhs, + }, }); } &mut GenericArgs::Parenthesized { .. } => { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index af283e6c0bc6f..03d16feb483a9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1979,7 +1979,7 @@ impl FnDecl { match &bounds[0] { GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => { let bindings = trait_.bindings().unwrap(); - FunctionRetTy::Return(bindings[0].ty.clone()) + FunctionRetTy::Return(bindings[0].ty().clone()) } _ => panic!("unexpected desugaring of async function"), } @@ -2937,11 +2937,8 @@ 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.node), + TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.node), TyKind::CVarArgs(_) => CVarArgs, - TyKind::AssocTyExistential(ref bounds) => { - ImplTrait(bounds.into_iter().map(|b| b.clean(cx)).collect()) - } } } } @@ -3057,7 +3054,9 @@ impl<'tcx> Clean for Ty<'tcx> { for pb in obj.projection_bounds() { bindings.push(TypeBinding { name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), - ty: pb.skip_binder().ty.clean(cx) + kind: TypeBindingKind::Equality { + ty: pb.skip_binder().ty.clean(cx) + }, }); } @@ -3113,7 +3112,9 @@ impl<'tcx> Clean for Ty<'tcx> { Some(TypeBinding { name: cx.tcx.associated_item(proj.projection_ty.item_def_id) .ident.name.clean(cx), - ty: proj.ty.clean(cx), + kind: TypeBindingKind::Equality { + ty: proj.ty.clean(cx), + }, }) } else { None @@ -3498,7 +3499,7 @@ pub enum GenericArgs { impl Clean for hir::GenericArgs { fn clean(&self, cx: &DocContext<'_>) -> GenericArgs { if self.parenthesized { - let output = self.bindings[0].ty.clean(cx); + let output = self.bindings[0].ty().clean(cx); GenericArgs::Parenthesized { inputs: self.inputs().clean(cx), output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None } @@ -4346,18 +4347,53 @@ impl Clean for attr::Deprecation { } } -/// An equality constraint on an associated type, e.g., `A = Bar` in `Foo` +/// An type binding on an associated type (e.g., `A = Bar` in `Foo` or +/// `A: Send + Sync` in `Foo`). #[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)] pub struct TypeBinding { pub name: String, - pub ty: Type + pub kind: TypeBindingKind, +} + +#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug, Hash)] +pub enum TypeBindingKind { + Equality { + ty: Type, + }, + Constraint { + bounds: Vec, + }, +} + +impl TypeBinding { + pub fn ty(&self) -> &Type { + match self.kind { + TypeBindingKind::Equality { ref ty } => ty, + _ => panic!("expected equality type binding for parenthesized generic args"), + } + } } impl Clean for hir::TypeBinding { fn clean(&self, cx: &DocContext<'_>) -> TypeBinding { TypeBinding { name: self.ident.name.clean(cx), - ty: self.ty.clean(cx) + kind: self.kind.clean(cx), + } + } +} + +impl Clean for hir::TypeBindingKind { + fn clean(&self, cx: &DocContext<'_>) -> TypeBindingKind { + match *self { + hir::TypeBindingKind::Equality { ref ty } => + TypeBindingKind::Equality { + ty: ty.clean(cx), + }, + hir::TypeBindingKind::Constraint { ref bounds } => + TypeBindingKind::Constraint { + bounds: bounds.into_iter().map(|b| b.clean(cx)).collect(), + }, } } } diff --git a/src/librustdoc/clean/simplify.rs b/src/librustdoc/clean/simplify.rs index 8ca570cb443c9..36e6a6003df09 100644 --- a/src/librustdoc/clean/simplify.rs +++ b/src/librustdoc/clean/simplify.rs @@ -91,7 +91,9 @@ pub fn where_clauses(cx: &DocContext<'_>, clauses: Vec) -> Vec { PP::AngleBracketed { ref mut bindings, .. } => { bindings.push(clean::TypeBinding { name: name.clone(), - ty: rhs.clone(), + kind: clean::TypeBindingKind::Equality { + ty: rhs.clone(), + }, }); } PP::Parenthesized { ref mut output, .. } => { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 38cde12100056..fa3bc3f5f4f8b 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -1019,11 +1019,26 @@ impl fmt::Display for clean::ImportSource { impl fmt::Display for clean::TypeBinding { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - if f.alternate() { - write!(f, "{} = {:#}", self.name, self.ty) - } else { - write!(f, "{} = {}", self.name, self.ty) + f.write_str(&self.name)?; + match self.kind { + clean::TypeBindingKind::Equality { ref ty } => { + if f.alternate() { + write!(f, " = {:#}", ty)?; + } else { + write!(f, " = {}", ty)?; + } + } + clean::TypeBindingKind::Constraint { ref bounds } => { + if !bounds.is_empty() { + if f.alternate() { + write!(f, ": {:#}", GenericBounds(bounds))?; + } else { + write!(f, ": {}", GenericBounds(bounds))?; + } + } + } } + Ok(()) } } From c105c28de0df081c29a789fb58250eebc48b5eed Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 20 May 2019 00:22:44 +0100 Subject: [PATCH 13/24] Fixed rebase fallout. --- src/librustc/hir/lowering.rs | 1 - src/libsyntax_pos/symbol.rs | 1 + 2 files changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 1bfff138d8dca..d6ad335525c14 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1431,7 +1431,6 @@ impl<'a> LoweringContext<'a> { parent_def_index, impl_trait_node_id, DefPathData::ImplTrait, - DefIndexAddressSpace::High, Mark::root(), DUMMY_SP ); diff --git a/src/libsyntax_pos/symbol.rs b/src/libsyntax_pos/symbol.rs index 8847e94127be6..4e080d115d2a8 100644 --- a/src/libsyntax_pos/symbol.rs +++ b/src/libsyntax_pos/symbol.rs @@ -141,6 +141,7 @@ symbols! { arm_target_feature, asm, associated_consts, + associated_type_bounds, associated_type_defaults, associated_types, async_await, From 10b6daa6c8e1e4b2a041c3a28cae8e1c139c1bd2 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 20 May 2019 01:08:52 +0100 Subject: [PATCH 14/24] Reblessed tests. --- .../libtest-json/output.json | 2 +- src/test/run-pass/multi-panic.rs | 2 +- .../rustdoc-ui/failed-doctest-output.stdout | 2 +- .../associated-type-bounds/duplicate.stderr | 7 +- .../associated-type-bounds/dyn-lcsit.stderr | 6 + .../implied-region-constraints.stderr | 9 +- .../ui/associated-type-bounds/lcsit.stderr | 6 + .../associated-types-path-2.stderr | 2 +- .../borrowck/borrowck-closures-two-mut.stderr | 104 ++---------- src/test/ui/borrowck/borrowck-reinit.stderr | 16 +- .../ui/borrowck/borrowck-storage-dead.stderr | 12 +- src/test/ui/borrowck/immutable-arg.stderr | 14 +- src/test/ui/borrowck/issue-41962.stderr | 24 +-- .../const-param-before-other-params.stderr | 12 +- .../deprecation-in-staged-api.stderr | 2 +- .../yield-while-local-borrowed.stderr | 32 +--- src/test/ui/indexing-requires-a-uint.stderr | 2 +- .../integer-literal-suffix-inference.stderr | 36 ++-- src/test/ui/issues/issue-13359.stderr | 4 +- src/test/ui/issues/issue-31910.stderr | 2 +- src/test/ui/issues/issue-45697-1.stderr | 14 +- src/test/ui/issues/issue-45697.stderr | 14 +- src/test/ui/issues/issue-46471-1.stderr | 17 +- src/test/ui/issues/issue-46471.stderr | 20 +-- src/test/ui/issues/issue-46472.stderr | 24 +-- .../liveness-assign-imm-local-notes.stderr | 51 ++---- ...od-ambig-one-trait-unknown-int-type.stderr | 2 +- .../ui/mismatched_types/issue-26480.stderr | 2 +- .../ui/moves/moves-based-on-type-tuple.stderr | 16 +- src/test/ui/nll/get_default.stderr | 58 ++----- .../ui/nll/loan_ends_mid_block_pair.stderr | 60 +------ .../ui/nll/loan_ends_mid_block_vec.stderr | 88 +--------- .../nll/region-ends-after-if-condition.stderr | 32 +--- src/test/ui/nll/return_from_loop.stderr | 32 +--- src/test/ui/numeric/const-scope.stderr | 2 +- src/test/ui/numeric/len.stderr | 2 +- src/test/ui/numeric/numeric-cast-2.stderr | 6 +- src/test/ui/numeric/numeric-cast.stderr | 156 +++++++++--------- src/test/ui/pattern/const-pat-ice.stderr | 2 +- src/test/ui/pub/pub-restricted.stderr | 19 ++- src/test/ui/repeat_count.stderr | 4 +- src/test/ui/shift-various-bad-types.stderr | 2 +- src/test/ui/symbol-names/basic.stderr | 2 +- src/test/ui/symbol-names/impl1.stderr | 4 +- ...ounds-inconsistent-projection-error.stderr | 2 +- .../ui/tutorial-suffix-inference-test.stderr | 4 +- 46 files changed, 255 insertions(+), 676 deletions(-) create mode 100644 src/test/ui/associated-type-bounds/dyn-lcsit.stderr create mode 100644 src/test/ui/associated-type-bounds/lcsit.stderr diff --git a/src/test/run-make-fulldeps/libtest-json/output.json b/src/test/run-make-fulldeps/libtest-json/output.json index c8b3d08186929..0caf268aa007f 100644 --- a/src/test/run-make-fulldeps/libtest-json/output.json +++ b/src/test/run-make-fulldeps/libtest-json/output.json @@ -2,7 +2,7 @@ { "type": "test", "event": "started", "name": "a" } { "type": "test", "name": "a", "event": "ok" } { "type": "test", "event": "started", "name": "b" } -{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:8:5\nnote: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" } +{ "type": "test", "name": "b", "event": "failed", "stdout": "thread 'main' panicked at 'assertion failed: false', f.rs:8:5\nnote: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.\n" } { "type": "test", "event": "started", "name": "c" } { "type": "test", "name": "c", "event": "ok" } { "type": "test", "event": "started", "name": "d" } diff --git a/src/test/run-pass/multi-panic.rs b/src/test/run-pass/multi-panic.rs index 900b2b2206f48..8bc0002065271 100644 --- a/src/test/run-pass/multi-panic.rs +++ b/src/test/run-pass/multi-panic.rs @@ -8,7 +8,7 @@ fn check_for_no_backtrace(test: std::process::Output) { let mut it = err.lines(); assert_eq!(it.next().map(|l| l.starts_with("thread '' panicked at")), Some(true)); - assert_eq!(it.next(), Some("note: Run with `RUST_BACKTRACE=1` \ + assert_eq!(it.next(), Some("note: run with `RUST_BACKTRACE=1` \ environment variable to display a backtrace.")); assert_eq!(it.next().map(|l| l.starts_with("thread 'main' panicked at")), Some(true)); assert_eq!(it.next(), None); diff --git a/src/test/rustdoc-ui/failed-doctest-output.stdout b/src/test/rustdoc-ui/failed-doctest-output.stdout index 0c42c652d786c..e362ecf349e45 100644 --- a/src/test/rustdoc-ui/failed-doctest-output.stdout +++ b/src/test/rustdoc-ui/failed-doctest-output.stdout @@ -27,7 +27,7 @@ stderr: stderr 1 stderr 2 thread 'main' panicked at 'oh no', $DIR/failed-doctest-output.rs:7:1 -note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. diff --git a/src/test/ui/associated-type-bounds/duplicate.stderr b/src/test/ui/associated-type-bounds/duplicate.stderr index fbf02ddc7032f..68367c916546c 100644 --- a/src/test/ui/associated-type-bounds/duplicate.stderr +++ b/src/test/ui/associated-type-bounds/duplicate.stderr @@ -1,3 +1,9 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/duplicate.rs:7:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + error[E0719]: the value of the associated type `Item` (from the trait `std::iter::Iterator`) is already specified --> $DIR/duplicate.rs:12:36 | @@ -624,4 +630,3 @@ error: could not find defining uses error: aborting due to 93 previous errors -For more information about this error, try `rustc --explain E0719`. diff --git a/src/test/ui/associated-type-bounds/dyn-lcsit.stderr b/src/test/ui/associated-type-bounds/dyn-lcsit.stderr new file mode 100644 index 0000000000000..5fe4818ef8fed --- /dev/null +++ b/src/test/ui/associated-type-bounds/dyn-lcsit.stderr @@ -0,0 +1,6 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/dyn-lcsit.rs:4:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr index b07b20272a8c0..9968f3e8bac5e 100644 --- a/src/test/ui/associated-type-bounds/implied-region-constraints.stderr +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.stderr @@ -2,9 +2,7 @@ error[E0623]: lifetime mismatch --> $DIR/implied-region-constraints.rs:19:64 | LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) - | ------------- - | | - | this type is declared with multiple lifetimes... + | ------------- this type is declared with multiple lifetimes... ... LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; | ^^^^^ ...but data with one lifetime flows into the other here @@ -13,13 +11,10 @@ error[E0623]: lifetime mismatch --> $DIR/implied-region-constraints.rs:40:72 | LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) - | -------------- - | | - | this type is declared with multiple lifetimes... + | -------------- this type is declared with multiple lifetimes... ... LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x; | ^^ ...but data with one lifetime flows into the other here error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0623`. diff --git a/src/test/ui/associated-type-bounds/lcsit.stderr b/src/test/ui/associated-type-bounds/lcsit.stderr new file mode 100644 index 0000000000000..8fda11beddc4f --- /dev/null +++ b/src/test/ui/associated-type-bounds/lcsit.stderr @@ -0,0 +1,6 @@ +warning: the feature `impl_trait_in_bindings` is incomplete and may cause the compiler to crash + --> $DIR/lcsit.rs:4:12 + | +LL | #![feature(impl_trait_in_bindings)] + | ^^^^^^^^^^^^^^^^^^^^^^ + diff --git a/src/test/ui/associated-types/associated-types-path-2.stderr b/src/test/ui/associated-types/associated-types-path-2.stderr index c25f12d008703..1405cb1b4736c 100644 --- a/src/test/ui/associated-types/associated-types-path-2.stderr +++ b/src/test/ui/associated-types/associated-types-path-2.stderr @@ -49,7 +49,7 @@ error[E0308]: mismatched types | LL | let _: i32 = f2(2i32); | ^^^^^^^^ expected i32, found u32 -help: you can convert an `u32` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `i32` and panic if the converted value wouldn't fit | LL | let _: i32 = f2(2i32).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr index e881201ddfcc0..bffb11640744c 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr +++ b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr @@ -1,80 +1,5 @@ -error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) - --> $DIR/borrowck-closures-two-mut.rs:14:24 - | -LL | let c1 = to_fn_mut(|| x = 4); - | -- - previous borrow occurs due to use of `x` in closure - | | - | first mutable borrow occurs here -LL | let c2 = to_fn_mut(|| x = 5); - | ^^ - borrow occurs due to use of `x` in closure - | | - | second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) - --> $DIR/borrowck-closures-two-mut.rs:26:24 - | -LL | let c1 = to_fn_mut(|| set(&mut x)); - | -- - previous borrow occurs due to use of `x` in closure - | | - | first mutable borrow occurs here -LL | let c2 = to_fn_mut(|| set(&mut x)); - | ^^ - borrow occurs due to use of `x` in closure - | | - | second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) - --> $DIR/borrowck-closures-two-mut.rs:34:24 - | -LL | let c1 = to_fn_mut(|| x = 5); - | -- - previous borrow occurs due to use of `x` in closure - | | - | first mutable borrow occurs here -LL | let c2 = to_fn_mut(|| set(&mut x)); - | ^^ - borrow occurs due to use of `x` in closure - | | - | second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) - --> $DIR/borrowck-closures-two-mut.rs:42:24 - | -LL | let c1 = to_fn_mut(|| x = 5); - | -- - previous borrow occurs due to use of `x` in closure - | | - | first mutable borrow occurs here -LL | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) - | ^^ - borrow occurs due to use of `x` in closure - | | - | second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `x` as mutable more than once at a time (Ast) - --> $DIR/borrowck-closures-two-mut.rs:55:24 - | -LL | let c1 = to_fn_mut(|| set(&mut *x.f)); - | -- - previous borrow occurs due to use of `x` in closure - | | - | first mutable borrow occurs here -LL | let c2 = to_fn_mut(|| set(&mut *x.f)); - | ^^ - borrow occurs due to use of `x` in closure - | | - | second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) - --> $DIR/borrowck-closures-two-mut.rs:14:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut.rs:12:24 | LL | let c1 = to_fn_mut(|| x = 4); | -- - first borrow occurs due to use of `x` in closure @@ -84,12 +9,11 @@ LL | let c2 = to_fn_mut(|| x = 5); | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -LL | LL | drop((c1, c2)); | -- first borrow later used here -error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) - --> $DIR/borrowck-closures-two-mut.rs:26:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut.rs:23:24 | LL | let c1 = to_fn_mut(|| set(&mut x)); | -- - first borrow occurs due to use of `x` in closure @@ -99,12 +23,11 @@ LL | let c2 = to_fn_mut(|| set(&mut x)); | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -LL | LL | drop((c1, c2)); | -- first borrow later used here -error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) - --> $DIR/borrowck-closures-two-mut.rs:34:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut.rs:30:24 | LL | let c1 = to_fn_mut(|| x = 5); | -- - first borrow occurs due to use of `x` in closure @@ -114,12 +37,11 @@ LL | let c2 = to_fn_mut(|| set(&mut x)); | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -LL | LL | drop((c1, c2)); | -- first borrow later used here -error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) - --> $DIR/borrowck-closures-two-mut.rs:42:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut.rs:37:24 | LL | let c1 = to_fn_mut(|| x = 5); | -- - first borrow occurs due to use of `x` in closure @@ -129,12 +51,12 @@ LL | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nes | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -... +LL | LL | drop((c1, c2)); | -- first borrow later used here -error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) - --> $DIR/borrowck-closures-two-mut.rs:55:24 +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/borrowck-closures-two-mut.rs:49:24 | LL | let c1 = to_fn_mut(|| set(&mut *x.f)); | -- - first borrow occurs due to use of `x` in closure @@ -144,10 +66,10 @@ LL | let c2 = to_fn_mut(|| set(&mut *x.f)); | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here -... +LL | LL | drop((c1, c2)); | -- first borrow later used here -error: aborting due to 10 previous errors +error: aborting due to 5 previous errors For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/borrowck/borrowck-reinit.stderr b/src/test/ui/borrowck/borrowck-reinit.stderr index 3618a7cb2cd39..f8f14b6435f08 100644 --- a/src/test/ui/borrowck/borrowck-reinit.stderr +++ b/src/test/ui/borrowck/borrowck-reinit.stderr @@ -1,15 +1,5 @@ -error[E0382]: use of moved value: `x` (Ast) - --> $DIR/borrowck-reinit.rs:8:16 - | -LL | drop(x); - | - value moved here -LL | let _ = (1,x); - | ^ value used here after move - | - = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait - -error[E0382]: use of moved value: `x` (Mir) - --> $DIR/borrowck-reinit.rs:8:16 +error[E0382]: use of moved value: `x` + --> $DIR/borrowck-reinit.rs:6:16 | LL | let mut x = Box::new(0); | ----- move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait @@ -19,6 +9,6 @@ LL | drop(x); LL | let _ = (1,x); | ^ value used here after move -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/borrowck/borrowck-storage-dead.stderr b/src/test/ui/borrowck/borrowck-storage-dead.stderr index c291ed224eb3c..5b9f49c2e7c92 100644 --- a/src/test/ui/borrowck/borrowck-storage-dead.stderr +++ b/src/test/ui/borrowck/borrowck-storage-dead.stderr @@ -1,15 +1,9 @@ -error[E0381]: use of possibly uninitialized variable: `x` (Ast) - --> $DIR/borrowck-storage-dead.rs:18:17 +error[E0381]: use of possibly uninitialized variable: `x` + --> $DIR/borrowck-storage-dead.rs:16:17 | LL | let _ = x + 1; | ^ use of possibly uninitialized `x` -error[E0381]: use of possibly uninitialized variable: `x` (Mir) - --> $DIR/borrowck-storage-dead.rs:18:17 - | -LL | let _ = x + 1; - | ^ use of possibly uninitialized `x` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0381`. diff --git a/src/test/ui/borrowck/immutable-arg.stderr b/src/test/ui/borrowck/immutable-arg.stderr index 8b21e92666674..7255ca327e753 100644 --- a/src/test/ui/borrowck/immutable-arg.stderr +++ b/src/test/ui/borrowck/immutable-arg.stderr @@ -1,19 +1,11 @@ -error[E0384]: cannot assign twice to immutable variable `_x` (Ast) - --> $DIR/immutable-arg.rs:4:5 - | -LL | fn foo(_x: u32) { - | -- first assignment to `_x` -LL | _x = 4; - | ^^^^^^ cannot assign twice to immutable variable - -error[E0384]: cannot assign to immutable argument `_x` (Mir) - --> $DIR/immutable-arg.rs:4:5 +error[E0384]: cannot assign to immutable argument `_x` + --> $DIR/immutable-arg.rs:2:5 | LL | fn foo(_x: u32) { | -- help: make this binding mutable: `mut _x` LL | _x = 4; | ^^^^^^ cannot assign to immutable argument -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/borrowck/issue-41962.stderr b/src/test/ui/borrowck/issue-41962.stderr index fd4d318b5ddf1..422d1605aa46b 100644 --- a/src/test/ui/borrowck/issue-41962.stderr +++ b/src/test/ui/borrowck/issue-41962.stderr @@ -1,29 +1,11 @@ -error[E0382]: use of partially moved value: `maybe` (Ast) - --> $DIR/issue-41962.rs:7:30 - | -LL | if let Some(thing) = maybe { - | ----- ^^^^^ value used here after move - | | - | value moved here - | - = note: move occurs because the value has type `std::vec::Vec`, which does not implement the `Copy` trait - -error[E0382]: use of moved value: `(maybe as std::prelude::v1::Some).0` (Ast) - --> $DIR/issue-41962.rs:7:21 - | -LL | if let Some(thing) = maybe { - | ^^^^^ value moved here in previous iteration of loop - | - = note: move occurs because the value has type `std::vec::Vec`, which does not implement the `Copy` trait - -error[E0382]: use of moved value (Mir) - --> $DIR/issue-41962.rs:7:21 +error[E0382]: use of moved value + --> $DIR/issue-41962.rs:5:21 | LL | if let Some(thing) = maybe { | ^^^^^ value moved here, in previous iteration of loop | = note: move occurs because value has type `std::vec::Vec`, which does not implement the `Copy` trait -error: aborting due to 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/const-generics/const-param-before-other-params.stderr b/src/test/ui/const-generics/const-param-before-other-params.stderr index 78f129e79ea24..33f981d1eba9b 100644 --- a/src/test/ui/const-generics/const-param-before-other-params.stderr +++ b/src/test/ui/const-generics/const-param-before-other-params.stderr @@ -4,17 +4,17 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ -error: type parameters must be declared prior to const parameters +error: lifetime parameters must be declared prior to const parameters --> $DIR/const-param-before-other-params.rs:4:21 | -LL | fn foo(_: &T) { - | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `` +LL | fn bar(_: &'a ()) { + | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>` -error: lifetime parameters must be declared prior to const parameters +error: type parameters must be declared prior to const parameters --> $DIR/const-param-before-other-params.rs:8:21 | -LL | fn bar(_: &'a ()) { - | --------------^^- help: reorder the parameters: lifetimes, then types, then consts: `<'a, const X: ()>` +LL | fn foo(_: &T) { + | --------------^- help: reorder the parameters: lifetimes, then types, then consts: `` error: aborting due to 2 previous errors diff --git a/src/test/ui/deprecation/deprecation-in-staged-api.stderr b/src/test/ui/deprecation/deprecation-in-staged-api.stderr index 6a8056ec2d9d6..c6881d5a5735f 100644 --- a/src/test/ui/deprecation/deprecation-in-staged-api.stderr +++ b/src/test/ui/deprecation/deprecation-in-staged-api.stderr @@ -1,4 +1,4 @@ -error: `#[deprecated]` cannot be used in staged api, use `#[rustc_deprecated]` instead +error: `#[deprecated]` cannot be used in staged API; use `#[rustc_deprecated]` instead --> $DIR/deprecation-in-staged-api.rs:8:1 | LL | fn main() { } diff --git a/src/test/ui/generator/yield-while-local-borrowed.stderr b/src/test/ui/generator/yield-while-local-borrowed.stderr index 56f425b7e70a0..c1513ef9b7157 100644 --- a/src/test/ui/generator/yield-while-local-borrowed.stderr +++ b/src/test/ui/generator/yield-while-local-borrowed.stderr @@ -1,39 +1,21 @@ -error[E0626]: borrow may still be in use when generator yields (Ast) - --> $DIR/yield-while-local-borrowed.rs:15:22 - | -LL | let a = &mut 3; - | ^ -... -LL | yield(); - | ------- possible yield occurs here - -error[E0626]: borrow may still be in use when generator yields (Ast) - --> $DIR/yield-while-local-borrowed.rs:43:22 - | -LL | let b = &a; - | ^ -... -LL | yield(); - | ------- possible yield occurs here - -error[E0626]: borrow may still be in use when generator yields (Mir) - --> $DIR/yield-while-local-borrowed.rs:15:17 +error[E0626]: borrow may still be in use when generator yields + --> $DIR/yield-while-local-borrowed.rs:13:17 | LL | let a = &mut 3; | ^^^^^^ -... +LL | LL | yield(); | ------- possible yield occurs here -error[E0626]: borrow may still be in use when generator yields (Mir) - --> $DIR/yield-while-local-borrowed.rs:43:21 +error[E0626]: borrow may still be in use when generator yields + --> $DIR/yield-while-local-borrowed.rs:40:21 | LL | let b = &a; | ^^ -... +LL | LL | yield(); | ------- possible yield occurs here -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0626`. diff --git a/src/test/ui/indexing-requires-a-uint.stderr b/src/test/ui/indexing-requires-a-uint.stderr index 9dafe1c24f1c2..3300db58d44c3 100644 --- a/src/test/ui/indexing-requires-a-uint.stderr +++ b/src/test/ui/indexing-requires-a-uint.stderr @@ -12,7 +12,7 @@ error[E0308]: mismatched types | LL | bar::(i); // i should not be re-coerced back to an isize | ^ expected isize, found usize -help: you can convert an `usize` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `isize` and panic if the converted value wouldn't fit | LL | bar::(i.try_into().unwrap()); // i should not be re-coerced back to an isize | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/integer-literal-suffix-inference.stderr b/src/test/ui/integer-literal-suffix-inference.stderr index b5b3f27f0e6cd..80b601dc4394b 100644 --- a/src/test/ui/integer-literal-suffix-inference.stderr +++ b/src/test/ui/integer-literal-suffix-inference.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | id_i8(a16); | ^^^ expected i8, found i16 -help: you can convert an `i16` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i16` to `i8` and panic if the converted value wouldn't fit | LL | id_i8(a16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ error[E0308]: mismatched types | LL | id_i8(a32); | ^^^ expected i8, found i32 -help: you can convert an `i32` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `i8` and panic if the converted value wouldn't fit | LL | id_i8(a32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ error[E0308]: mismatched types | LL | id_i8(a64); | ^^^ expected i8, found i64 -help: you can convert an `i64` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i8` and panic if the converted value wouldn't fit | LL | id_i8(a64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ error[E0308]: mismatched types | LL | id_i16(a32); | ^^^ expected i16, found i32 -help: you can convert an `i32` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `i16` and panic if the converted value wouldn't fit | LL | id_i16(a32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ error[E0308]: mismatched types | LL | id_i16(a64); | ^^^ expected i16, found i64 -help: you can convert an `i64` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i16` and panic if the converted value wouldn't fit | LL | id_i16(a64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -80,7 +80,7 @@ error[E0308]: mismatched types | LL | id_i32(a64); | ^^^ expected i32, found i64 -help: you can convert an `i64` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i32` and panic if the converted value wouldn't fit | LL | id_i32(a64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -117,7 +117,7 @@ error[E0308]: mismatched types | LL | id_i8(c16); | ^^^ expected i8, found i16 -help: you can convert an `i16` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i16` to `i8` and panic if the converted value wouldn't fit | LL | id_i8(c16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -127,7 +127,7 @@ error[E0308]: mismatched types | LL | id_i8(c32); | ^^^ expected i8, found i32 -help: you can convert an `i32` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `i8` and panic if the converted value wouldn't fit | LL | id_i8(c32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -137,7 +137,7 @@ error[E0308]: mismatched types | LL | id_i8(c64); | ^^^ expected i8, found i64 -help: you can convert an `i64` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i8` and panic if the converted value wouldn't fit | LL | id_i8(c64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -156,7 +156,7 @@ error[E0308]: mismatched types | LL | id_i16(c32); | ^^^ expected i16, found i32 -help: you can convert an `i32` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `i16` and panic if the converted value wouldn't fit | LL | id_i16(c32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -166,7 +166,7 @@ error[E0308]: mismatched types | LL | id_i16(c64); | ^^^ expected i16, found i64 -help: you can convert an `i64` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i16` and panic if the converted value wouldn't fit | LL | id_i16(c64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -194,7 +194,7 @@ error[E0308]: mismatched types | LL | id_i32(c64); | ^^^ expected i32, found i64 -help: you can convert an `i64` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i32` and panic if the converted value wouldn't fit | LL | id_i32(c64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -231,7 +231,7 @@ error[E0308]: mismatched types | LL | id_u8(b16); | ^^^ expected u8, found u16 -help: you can convert an `u16` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `u8` and panic if the converted value wouldn't fit | LL | id_u8(b16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -241,7 +241,7 @@ error[E0308]: mismatched types | LL | id_u8(b32); | ^^^ expected u8, found u32 -help: you can convert an `u32` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `u8` and panic if the converted value wouldn't fit | LL | id_u8(b32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -251,7 +251,7 @@ error[E0308]: mismatched types | LL | id_u8(b64); | ^^^ expected u8, found u64 -help: you can convert an `u64` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `u8` and panic if the converted value wouldn't fit | LL | id_u8(b64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -270,7 +270,7 @@ error[E0308]: mismatched types | LL | id_u16(b32); | ^^^ expected u16, found u32 -help: you can convert an `u32` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `u16` and panic if the converted value wouldn't fit | LL | id_u16(b32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -280,7 +280,7 @@ error[E0308]: mismatched types | LL | id_u16(b64); | ^^^ expected u16, found u64 -help: you can convert an `u64` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `u16` and panic if the converted value wouldn't fit | LL | id_u16(b64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ @@ -308,7 +308,7 @@ error[E0308]: mismatched types | LL | id_u32(b64); | ^^^ expected u32, found u64 -help: you can convert an `u64` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `u32` and panic if the converted value wouldn't fit | LL | id_u32(b64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-13359.stderr b/src/test/ui/issues/issue-13359.stderr index b16b7a5b2cf04..7cfd754f72d8e 100644 --- a/src/test/ui/issues/issue-13359.stderr +++ b/src/test/ui/issues/issue-13359.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | foo(1*(1 as isize)); | ^^^^^^^^^^^^^^ expected i16, found isize -help: you can convert an `isize` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `i16` and panic if the converted value wouldn't fit | LL | foo((1*(1 as isize)).try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ error[E0308]: mismatched types | LL | bar(1*(1 as usize)); | ^^^^^^^^^^^^^^ expected u32, found usize -help: you can convert an `usize` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `u32` and panic if the converted value wouldn't fit | LL | bar((1*(1 as usize)).try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-31910.stderr b/src/test/ui/issues/issue-31910.stderr index 8dd9287ffec79..e7555b958a3d4 100644 --- a/src/test/ui/issues/issue-31910.stderr +++ b/src/test/ui/issues/issue-31910.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | X = Trait::Number, | ^^^^^^^^^^^^^ expected isize, found i32 -help: you can convert an `i32` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit | LL | X = Trait::Number.try_into().unwrap(), | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/issues/issue-45697-1.stderr b/src/test/ui/issues/issue-45697-1.stderr index 854e18003f330..30c69f19658c8 100644 --- a/src/test/ui/issues/issue-45697-1.stderr +++ b/src/test/ui/issues/issue-45697-1.stderr @@ -1,12 +1,4 @@ -error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Ast) - --> $DIR/issue-45697-1.rs:20:9 - | -LL | let z = copy_borrowed_ptr(&mut y); - | - borrow of `*y.pointer` occurs here -LL | *y.pointer += 1; - | ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here - -error[E0503]: cannot use `*y.pointer` because it was mutably borrowed (Mir) +error[E0503]: cannot use `*y.pointer` because it was mutably borrowed --> $DIR/issue-45697-1.rs:20:9 | LL | let z = copy_borrowed_ptr(&mut y); @@ -17,7 +9,7 @@ LL | *y.pointer += 1; LL | *z.pointer += 1; | --------------- borrow later used here -error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Mir) +error[E0506]: cannot assign to `*y.pointer` because it is borrowed --> $DIR/issue-45697-1.rs:20:9 | LL | let z = copy_borrowed_ptr(&mut y); @@ -28,7 +20,7 @@ LL | *y.pointer += 1; LL | *z.pointer += 1; | --------------- borrow later used here -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0503, E0506. For more information about an error, try `rustc --explain E0503`. diff --git a/src/test/ui/issues/issue-45697.stderr b/src/test/ui/issues/issue-45697.stderr index 01ae416b1cf14..26749d36f0b7b 100644 --- a/src/test/ui/issues/issue-45697.stderr +++ b/src/test/ui/issues/issue-45697.stderr @@ -1,12 +1,4 @@ -error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Ast) - --> $DIR/issue-45697.rs:20:9 - | -LL | let z = copy_borrowed_ptr(&mut y); - | - borrow of `*y.pointer` occurs here -LL | *y.pointer += 1; - | ^^^^^^^^^^^^^^^ assignment to borrowed `*y.pointer` occurs here - -error[E0503]: cannot use `*y.pointer` because it was mutably borrowed (Mir) +error[E0503]: cannot use `*y.pointer` because it was mutably borrowed --> $DIR/issue-45697.rs:20:9 | LL | let z = copy_borrowed_ptr(&mut y); @@ -17,7 +9,7 @@ LL | *y.pointer += 1; LL | *z.pointer += 1; | --------------- borrow later used here -error[E0506]: cannot assign to `*y.pointer` because it is borrowed (Mir) +error[E0506]: cannot assign to `*y.pointer` because it is borrowed --> $DIR/issue-45697.rs:20:9 | LL | let z = copy_borrowed_ptr(&mut y); @@ -28,7 +20,7 @@ LL | *y.pointer += 1; LL | *z.pointer += 1; | --------------- borrow later used here -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors Some errors have detailed explanations: E0503, E0506. For more information about an error, try `rustc --explain E0503`. diff --git a/src/test/ui/issues/issue-46471-1.stderr b/src/test/ui/issues/issue-46471-1.stderr index 51026c9f2d834..b09f31729a5fd 100644 --- a/src/test/ui/issues/issue-46471-1.stderr +++ b/src/test/ui/issues/issue-46471-1.stderr @@ -1,16 +1,5 @@ -error[E0597]: `z` does not live long enough (Ast) - --> $DIR/issue-46471-1.rs:6:14 - | -LL | &mut z - | ^ borrowed value does not live long enough -LL | }; - | - `z` dropped here while still borrowed -... -LL | } - | - borrowed value needs to live until here - -error[E0597]: `z` does not live long enough (Mir) - --> $DIR/issue-46471-1.rs:6:9 +error[E0597]: `z` does not live long enough + --> $DIR/issue-46471-1.rs:4:9 | LL | &mut z | ^^^^^^ @@ -20,6 +9,6 @@ LL | &mut z LL | }; | - `z` dropped here while still borrowed -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0597`. diff --git a/src/test/ui/issues/issue-46471.stderr b/src/test/ui/issues/issue-46471.stderr index 90202e307eb11..935414c1f3f9d 100644 --- a/src/test/ui/issues/issue-46471.stderr +++ b/src/test/ui/issues/issue-46471.stderr @@ -1,21 +1,9 @@ -error[E0597]: `x` does not live long enough (Ast) - --> $DIR/issue-46471.rs:5:6 - | -LL | &x - | ^ borrowed value does not live long enough -... -LL | } - | - borrowed value only lives until here - | - = note: borrowed value must be valid for the static lifetime... - -error[E0515]: cannot return reference to local variable `x` (Mir) - --> $DIR/issue-46471.rs:5:5 +error[E0515]: cannot return reference to local variable `x` + --> $DIR/issue-46471.rs:3:5 | LL | &x | ^^ returns a reference to data owned by the current function -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0515, E0597. -For more information about an error, try `rustc --explain E0515`. +For more information about this error, try `rustc --explain E0515`. diff --git a/src/test/ui/issues/issue-46472.stderr b/src/test/ui/issues/issue-46472.stderr index 0cc93a081b2af..6e561e03a8b7a 100644 --- a/src/test/ui/issues/issue-46472.stderr +++ b/src/test/ui/issues/issue-46472.stderr @@ -1,20 +1,5 @@ -error[E0597]: borrowed value does not live long enough (Ast) - --> $DIR/issue-46472.rs:4:10 - | -LL | &mut 4 - | ^ temporary value does not live long enough -... -LL | } - | - temporary value only lives until here - | -note: borrowed value must be valid for the lifetime 'a as defined on the function body at 3:8... - --> $DIR/issue-46472.rs:3:8 - | -LL | fn bar<'a>() -> &'a mut u32 { - | ^^ - -error[E0515]: cannot return reference to temporary value (Mir) - --> $DIR/issue-46472.rs:4:5 +error[E0515]: cannot return reference to temporary value + --> $DIR/issue-46472.rs:2:5 | LL | &mut 4 | ^^^^^- @@ -22,7 +7,6 @@ LL | &mut 4 | | temporary value created here | returns a reference to data owned by the current function -error: aborting due to 2 previous errors +error: aborting due to previous error -Some errors have detailed explanations: E0515, E0597. -For more information about an error, try `rustc --explain E0515`. +For more information about this error, try `rustc --explain E0515`. diff --git a/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr b/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr index e15290f0b9ee9..c646912d3b679 100644 --- a/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr +++ b/src/test/ui/lifetimes/lifetime-errors/liveness-assign-imm-local-notes.stderr @@ -1,36 +1,5 @@ -error[E0384]: cannot assign twice to immutable variable `x` (Ast) - --> $DIR/liveness-assign-imm-local-notes.rs:13:9 - | -LL | x = 2; - | ----- first assignment to `x` -LL | x = 3; - | ^^^^^ cannot assign twice to immutable variable - -error[E0384]: cannot assign twice to immutable variable `x` (Ast) - --> $DIR/liveness-assign-imm-local-notes.rs:25:13 - | -LL | x = 2; - | ----- first assignment to `x` -LL | x = 3; - | ^^^^^ cannot assign twice to immutable variable - -error[E0384]: cannot assign twice to immutable variable `x` (Ast) - --> $DIR/liveness-assign-imm-local-notes.rs:35:13 - | -LL | x = 1; - | ^^^^^ cannot assign twice to immutable variable - -error[E0384]: cannot assign twice to immutable variable `x` (Ast) - --> $DIR/liveness-assign-imm-local-notes.rs:38:13 - | -LL | x = 1; - | ----- first assignment to `x` -... -LL | x = 2; - | ^^^^^ cannot assign twice to immutable variable - -error[E0384]: cannot assign twice to immutable variable `x` (Mir) - --> $DIR/liveness-assign-imm-local-notes.rs:13:9 +error[E0384]: cannot assign twice to immutable variable `x` + --> $DIR/liveness-assign-imm-local-notes.rs:10:9 | LL | let x; | - help: make this binding mutable: `mut x` @@ -40,8 +9,8 @@ LL | x = 2; LL | x = 3; | ^^^^^ cannot assign twice to immutable variable -error[E0384]: cannot assign twice to immutable variable `x` (Mir) - --> $DIR/liveness-assign-imm-local-notes.rs:25:13 +error[E0384]: cannot assign twice to immutable variable `x` + --> $DIR/liveness-assign-imm-local-notes.rs:21:13 | LL | let x; | - help: make this binding mutable: `mut x` @@ -51,8 +20,8 @@ LL | x = 2; LL | x = 3; | ^^^^^ cannot assign twice to immutable variable -error[E0384]: cannot assign twice to immutable variable `x` (Mir) - --> $DIR/liveness-assign-imm-local-notes.rs:35:13 +error[E0384]: cannot assign twice to immutable variable `x` + --> $DIR/liveness-assign-imm-local-notes.rs:30:13 | LL | let x; | - help: make this binding mutable: `mut x` @@ -60,18 +29,18 @@ LL | let x; LL | x = 1; | ^^^^^ cannot assign twice to immutable variable -error[E0384]: cannot assign twice to immutable variable `x` (Mir) - --> $DIR/liveness-assign-imm-local-notes.rs:38:13 +error[E0384]: cannot assign twice to immutable variable `x` + --> $DIR/liveness-assign-imm-local-notes.rs:32:13 | LL | let x; | - help: make this binding mutable: `mut x` ... LL | x = 1; | ----- first assignment to `x` -... +LL | } else { LL | x = 2; | ^^^^^ cannot assign twice to immutable variable -error: aborting due to 8 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0384`. diff --git a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr index 49c72a655e57a..b1bd749bef4a2 100644 --- a/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr +++ b/src/test/ui/methods/method-ambig-one-trait-unknown-int-type.stderr @@ -11,7 +11,7 @@ error[E0308]: mismatched types | LL | let y: usize = x.foo(); | ^^^^^^^ expected usize, found isize -help: you can convert an `isize` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit | LL | let y: usize = x.foo().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/mismatched_types/issue-26480.stderr b/src/test/ui/mismatched_types/issue-26480.stderr index 1a81df8e2c464..881d9fd32029e 100644 --- a/src/test/ui/mismatched_types/issue-26480.stderr +++ b/src/test/ui/mismatched_types/issue-26480.stderr @@ -6,7 +6,7 @@ LL | $arr.len() * size_of($arr[0])); ... LL | write!(hello); | -------------- in this macro invocation -help: you can convert an `usize` to `u64` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `u64` and panic if the converted value wouldn't fit | LL | ($arr.len() * size_of($arr[0])).try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/moves/moves-based-on-type-tuple.stderr b/src/test/ui/moves/moves-based-on-type-tuple.stderr index c49dbdab40210..2e1ddbdf57f98 100644 --- a/src/test/ui/moves/moves-based-on-type-tuple.stderr +++ b/src/test/ui/moves/moves-based-on-type-tuple.stderr @@ -1,15 +1,5 @@ -error[E0382]: use of moved value: `x` (Ast) - --> $DIR/moves-based-on-type-tuple.rs:6:13 - | -LL | box (x, x) - | - ^ value used here after move - | | - | value moved here - | - = note: move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait - -error[E0382]: use of moved value: `x` (Mir) - --> $DIR/moves-based-on-type-tuple.rs:6:13 +error[E0382]: use of moved value: `x` + --> $DIR/moves-based-on-type-tuple.rs:4:13 | LL | fn dup(x: Box) -> Box<(Box,Box)> { | - move occurs because `x` has type `std::boxed::Box`, which does not implement the `Copy` trait @@ -18,6 +8,6 @@ LL | box (x, x) | | | value moved here -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/nll/get_default.stderr b/src/test/ui/nll/get_default.stderr index abb5343845b57..af79771e7e1b9 100644 --- a/src/test/ui/nll/get_default.stderr +++ b/src/test/ui/nll/get_default.stderr @@ -1,41 +1,5 @@ -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Ast) - --> $DIR/get_default.rs:23:17 - | -LL | match map.get() { - | --- immutable borrow occurs here -... -LL | map.set(String::new()); // Ideally, this would not error. - | ^^^ mutable borrow occurs here -... -LL | } - | - immutable borrow ends here - -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Ast) - --> $DIR/get_default.rs:35:17 - | -LL | match map.get() { - | --- immutable borrow occurs here -LL | Some(v) => { -LL | map.set(String::new()); // Both AST and MIR error here - | ^^^ mutable borrow occurs here -... -LL | } - | - immutable borrow ends here - -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Ast) - --> $DIR/get_default.rs:41:17 - | -LL | match map.get() { - | --- immutable borrow occurs here -... -LL | map.set(String::new()); // Ideally, just AST would error here - | ^^^ mutable borrow occurs here -... -LL | } - | - immutable borrow ends here - -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir) - --> $DIR/get_default.rs:23:17 +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable + --> $DIR/get_default.rs:21:17 | LL | fn ok(map: &mut Map) -> &String { | - let's call the lifetime of this reference `'1` @@ -47,10 +11,10 @@ LL | return v; | - returning this value requires that `*map` is borrowed for `'1` ... LL | map.set(String::new()); // Ideally, this would not error. - | ^^^ mutable borrow occurs here + | ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir) - --> $DIR/get_default.rs:35:17 +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable + --> $DIR/get_default.rs:32:17 | LL | fn err(map: &mut Map) -> &String { | - let's call the lifetime of this reference `'1` @@ -59,13 +23,13 @@ LL | match map.get() { | --- immutable borrow occurs here LL | Some(v) => { LL | map.set(String::new()); // Both AST and MIR error here - | ^^^ mutable borrow occurs here -... + | ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here +LL | LL | return v; | - returning this value requires that `*map` is borrowed for `'1` -error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable (Mir) - --> $DIR/get_default.rs:41:17 +error[E0502]: cannot borrow `*map` as mutable because it is also borrowed as immutable + --> $DIR/get_default.rs:37:17 | LL | fn err(map: &mut Map) -> &String { | - let's call the lifetime of this reference `'1` @@ -77,8 +41,8 @@ LL | return v; | - returning this value requires that `*map` is borrowed for `'1` ... LL | map.set(String::new()); // Ideally, just AST would error here - | ^^^ mutable borrow occurs here + | ^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here -error: aborting due to 6 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/nll/loan_ends_mid_block_pair.stderr b/src/test/ui/nll/loan_ends_mid_block_pair.stderr index 85703bda31c4e..eb8442b31d7c7 100644 --- a/src/test/ui/nll/loan_ends_mid_block_pair.stderr +++ b/src/test/ui/nll/loan_ends_mid_block_pair.stderr @@ -1,59 +1,5 @@ -error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) - --> $DIR/loan_ends_mid_block_pair.rs:14:5 - | -LL | let c = &mut data.0; - | ------ borrow of `data.0` occurs here -LL | capitalize(c); -LL | data.0 = 'e'; - | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here - -error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) - --> $DIR/loan_ends_mid_block_pair.rs:17:5 - | -LL | let c = &mut data.0; - | ------ borrow of `data.0` occurs here -... -LL | data.0 = 'f'; - | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here - -error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) - --> $DIR/loan_ends_mid_block_pair.rs:19:5 - | -LL | let c = &mut data.0; - | ------ borrow of `data.0` occurs here -... -LL | data.0 = 'g'; - | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here - -error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) - --> $DIR/loan_ends_mid_block_pair.rs:28:5 - | -LL | let c = &mut data.0; - | ------ borrow of `data.0` occurs here -LL | capitalize(c); -LL | data.0 = 'e'; - | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here - -error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) - --> $DIR/loan_ends_mid_block_pair.rs:30:5 - | -LL | let c = &mut data.0; - | ------ borrow of `data.0` occurs here -... -LL | data.0 = 'f'; - | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here - -error[E0506]: cannot assign to `data.0` because it is borrowed (Ast) - --> $DIR/loan_ends_mid_block_pair.rs:32:5 - | -LL | let c = &mut data.0; - | ------ borrow of `data.0` occurs here -... -LL | data.0 = 'g'; - | ^^^^^^^^^^^^ assignment to borrowed `data.0` occurs here - -error[E0506]: cannot assign to `data.0` because it is borrowed (Mir) - --> $DIR/loan_ends_mid_block_pair.rs:14:5 +error[E0506]: cannot assign to `data.0` because it is borrowed + --> $DIR/loan_ends_mid_block_pair.rs:12:5 | LL | let c = &mut data.0; | ----------- borrow of `data.0` occurs here @@ -64,6 +10,6 @@ LL | data.0 = 'e'; LL | capitalize(c); | - borrow later used here -error: aborting due to 7 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/loan_ends_mid_block_vec.stderr b/src/test/ui/nll/loan_ends_mid_block_vec.stderr index a3f1391f00140..c0b97bea348c4 100644 --- a/src/test/ui/nll/loan_ends_mid_block_vec.stderr +++ b/src/test/ui/nll/loan_ends_mid_block_vec.stderr @@ -1,77 +1,5 @@ -error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) - --> $DIR/loan_ends_mid_block_vec.rs:13:5 - | -LL | let slice = &mut data; - | ---- first mutable borrow occurs here -LL | capitalize(slice); -LL | data.push('d'); - | ^^^^ second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) - --> $DIR/loan_ends_mid_block_vec.rs:16:5 - | -LL | let slice = &mut data; - | ---- first mutable borrow occurs here -... -LL | data.push('e'); - | ^^^^ second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) - --> $DIR/loan_ends_mid_block_vec.rs:19:5 - | -LL | let slice = &mut data; - | ---- first mutable borrow occurs here -... -LL | data.push('f'); - | ^^^^ second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) - --> $DIR/loan_ends_mid_block_vec.rs:29:5 - | -LL | let slice = &mut data; - | ---- first mutable borrow occurs here -LL | capitalize(slice); -LL | data.push('d'); - | ^^^^ second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) - --> $DIR/loan_ends_mid_block_vec.rs:31:5 - | -LL | let slice = &mut data; - | ---- first mutable borrow occurs here -... -LL | data.push('e'); - | ^^^^ second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `data` as mutable more than once at a time (Ast) - --> $DIR/loan_ends_mid_block_vec.rs:33:5 - | -LL | let slice = &mut data; - | ---- first mutable borrow occurs here -... -LL | data.push('f'); - | ^^^^ second mutable borrow occurs here -LL | -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `data` as mutable more than once at a time (Mir) - --> $DIR/loan_ends_mid_block_vec.rs:13:5 +error[E0499]: cannot borrow `data` as mutable more than once at a time + --> $DIR/loan_ends_mid_block_vec.rs:11:5 | LL | let slice = &mut data; | --------- first mutable borrow occurs here @@ -82,8 +10,8 @@ LL | data.push('d'); LL | capitalize(slice); | ----- first borrow later used here -error[E0499]: cannot borrow `data` as mutable more than once at a time (Mir) - --> $DIR/loan_ends_mid_block_vec.rs:16:5 +error[E0499]: cannot borrow `data` as mutable more than once at a time + --> $DIR/loan_ends_mid_block_vec.rs:13:5 | LL | let slice = &mut data; | --------- first mutable borrow occurs here @@ -94,18 +22,18 @@ LL | data.push('e'); LL | capitalize(slice); | ----- first borrow later used here -error[E0499]: cannot borrow `data` as mutable more than once at a time (Mir) - --> $DIR/loan_ends_mid_block_vec.rs:19:5 +error[E0499]: cannot borrow `data` as mutable more than once at a time + --> $DIR/loan_ends_mid_block_vec.rs:15:5 | LL | let slice = &mut data; | --------- first mutable borrow occurs here ... LL | data.push('f'); | ^^^^ second mutable borrow occurs here -... +LL | LL | capitalize(slice); | ----- first borrow later used here -error: aborting due to 9 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/nll/region-ends-after-if-condition.stderr b/src/test/ui/nll/region-ends-after-if-condition.stderr index aa876a0bcb3bf..c03e385790616 100644 --- a/src/test/ui/nll/region-ends-after-if-condition.stderr +++ b/src/test/ui/nll/region-ends-after-if-condition.stderr @@ -1,39 +1,15 @@ -error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable (Ast) - --> $DIR/region-ends-after-if-condition.rs:19:9 - | -LL | let value = &my_struct.field; - | --------------- immutable borrow occurs here -LL | if value.is_empty() { -LL | my_struct.field.push_str("Hello, world!"); - | ^^^^^^^^^^^^^^^ mutable borrow occurs here -... -LL | } - | - immutable borrow ends here - -error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable (Ast) - --> $DIR/region-ends-after-if-condition.rs:29:9 - | -LL | let value = &my_struct.field; - | --------------- immutable borrow occurs here -LL | if value.is_empty() { -LL | my_struct.field.push_str("Hello, world!"); - | ^^^^^^^^^^^^^^^ mutable borrow occurs here -... -LL | } - | - immutable borrow ends here - -error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable (Mir) - --> $DIR/region-ends-after-if-condition.rs:29:9 +error[E0502]: cannot borrow `my_struct.field` as mutable because it is also borrowed as immutable + --> $DIR/region-ends-after-if-condition.rs:26:9 | LL | let value = &my_struct.field; | ---------------- immutable borrow occurs here LL | if value.is_empty() { LL | my_struct.field.push_str("Hello, world!"); - | ^^^^^^^^^^^^^^^ mutable borrow occurs here + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here ... LL | drop(value); | ----- immutable borrow later used here -error: aborting due to 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0502`. diff --git a/src/test/ui/nll/return_from_loop.stderr b/src/test/ui/nll/return_from_loop.stderr index 09882d55cb70e..efd56ea2dd542 100644 --- a/src/test/ui/nll/return_from_loop.stderr +++ b/src/test/ui/nll/return_from_loop.stderr @@ -1,39 +1,15 @@ -error[E0499]: cannot borrow `my_struct.field` as mutable more than once at a time (Ast) - --> $DIR/return_from_loop.rs:22:9 - | -LL | let value = &mut my_struct.field; - | --------------- first mutable borrow occurs here -LL | loop { -LL | my_struct.field.push_str("Hello, world!"); - | ^^^^^^^^^^^^^^^ second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `my_struct.field` as mutable more than once at a time (Ast) - --> $DIR/return_from_loop.rs:35:9 - | -LL | let value = &mut my_struct.field; - | --------------- first mutable borrow occurs here -LL | loop { -LL | my_struct.field.push_str("Hello, world!"); - | ^^^^^^^^^^^^^^^ second mutable borrow occurs here -... -LL | } - | - first borrow ends here - -error[E0499]: cannot borrow `my_struct.field` as mutable more than once at a time (Mir) - --> $DIR/return_from_loop.rs:22:9 +error[E0499]: cannot borrow `my_struct.field` as mutable more than once at a time + --> $DIR/return_from_loop.rs:20:9 | LL | let value = &mut my_struct.field; | -------------------- first mutable borrow occurs here LL | loop { LL | my_struct.field.push_str("Hello, world!"); | ^^^^^^^^^^^^^^^ second mutable borrow occurs here -... +LL | LL | value.len(); | ----- first borrow later used here -error: aborting due to 3 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0499`. diff --git a/src/test/ui/numeric/const-scope.stderr b/src/test/ui/numeric/const-scope.stderr index ead3a79da0270..3f69bcc7d4a2f 100644 --- a/src/test/ui/numeric/const-scope.stderr +++ b/src/test/ui/numeric/const-scope.stderr @@ -37,7 +37,7 @@ error[E0308]: mismatched types | LL | let d: i8 = c; | ^ expected i8, found i32 -help: you can convert an `i32` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `i8` and panic if the converted value wouldn't fit | LL | let d: i8 = c.try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/numeric/len.stderr b/src/test/ui/numeric/len.stderr index 5a9349b4c0f29..c767bdd9bd5a5 100644 --- a/src/test/ui/numeric/len.stderr +++ b/src/test/ui/numeric/len.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | test(array.len()); | ^^^^^^^^^^^ expected u32, found usize -help: you can convert an `usize` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `u32` and panic if the converted value wouldn't fit | LL | test(array.len().try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/numeric/numeric-cast-2.stderr b/src/test/ui/numeric/numeric-cast-2.stderr index be4411e630bec..f58389ce96c3b 100644 --- a/src/test/ui/numeric/numeric-cast-2.stderr +++ b/src/test/ui/numeric/numeric-cast-2.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | let x: u16 = foo(); | ^^^^^ expected u16, found i32 -help: you can convert an `i32` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `u16` and panic if the converted value wouldn't fit | LL | let x: u16 = foo().try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ error[E0308]: mismatched types | LL | let y: i64 = x + x; | ^^^^^ expected i64, found u16 -help: you can convert an `u16` to `i64` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `i64` and panic if the converted value wouldn't fit | LL | let y: i64 = (x + x).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ error[E0308]: mismatched types | LL | let z: i32 = x + x; | ^^^^^ expected i32, found u16 -help: you can convert an `u16` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `i32` and panic if the converted value wouldn't fit | LL | let z: i32 = (x + x).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/numeric/numeric-cast.stderr b/src/test/ui/numeric/numeric-cast.stderr index 9e7dcf7e41b55..e66b83f2b39f5 100644 --- a/src/test/ui/numeric/numeric-cast.stderr +++ b/src/test/ui/numeric/numeric-cast.stderr @@ -3,7 +3,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected usize, found u64 -help: you can convert an `u64` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `usize` and panic if the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -13,7 +13,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected usize, found u32 -help: you can convert an `u32` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `usize` and panic if the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -23,7 +23,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected usize, found u16 -help: you can convert an `u16` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `usize` and panic if the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -33,7 +33,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected usize, found u8 -help: you can convert an `u8` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `u8` to `usize` and panic if the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -43,7 +43,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected usize, found isize -help: you can convert an `isize` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -53,7 +53,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected usize, found i64 -help: you can convert an `i64` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `usize` and panic if the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -63,7 +63,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected usize, found i32 -help: you can convert an `i32` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `usize` and panic if the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -73,7 +73,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected usize, found i16 -help: you can convert an `i16` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `i16` to `usize` and panic if the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -83,7 +83,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected usize, found i8 -help: you can convert an `i8` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `i8` to `usize` and panic if the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -93,7 +93,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected isize, found usize -help: you can convert an `usize` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `isize` and panic if the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -103,7 +103,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected isize, found u64 -help: you can convert an `u64` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `isize` and panic if the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -113,7 +113,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected isize, found u32 -help: you can convert an `u32` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `isize` and panic if the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -123,7 +123,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected isize, found u16 -help: you can convert an `u16` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `isize` and panic if the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -133,7 +133,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected isize, found u8 -help: you can convert an `u8` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `u8` to `isize` and panic if the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -143,7 +143,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected isize, found i64 -help: you can convert an `i64` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `isize` and panic if the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -153,7 +153,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected isize, found i32 -help: you can convert an `i32` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `isize` and panic if the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -163,7 +163,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected isize, found i16 -help: you can convert an `i16` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `i16` to `isize` and panic if the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -173,7 +173,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected isize, found i8 -help: you can convert an `i8` to `isize` or panic if it the converted value wouldn't fit +help: you can convert an `i8` to `isize` and panic if the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -183,7 +183,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected u64, found usize -help: you can convert an `usize` to `u64` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `u64` and panic if the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -220,7 +220,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected u64, found isize -help: you can convert an `isize` to `u64` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `u64` and panic if the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -230,7 +230,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected u64, found i64 -help: you can convert an `i64` to `u64` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `u64` and panic if the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -240,7 +240,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected u64, found i32 -help: you can convert an `i32` to `u64` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `u64` and panic if the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -250,7 +250,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected u64, found i16 -help: you can convert an `i16` to `u64` or panic if it the converted value wouldn't fit +help: you can convert an `i16` to `u64` and panic if the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -260,7 +260,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected u64, found i8 -help: you can convert an `i8` to `u64` or panic if it the converted value wouldn't fit +help: you can convert an `i8` to `u64` and panic if the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -270,7 +270,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected i64, found usize -help: you can convert an `usize` to `i64` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `i64` and panic if the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -280,7 +280,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected i64, found u64 -help: you can convert an `u64` to `i64` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `i64` and panic if the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -290,7 +290,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected i64, found u32 -help: you can convert an `u32` to `i64` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `i64` and panic if the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -300,7 +300,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected i64, found u16 -help: you can convert an `u16` to `i64` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `i64` and panic if the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -310,7 +310,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected i64, found u8 -help: you can convert an `u8` to `i64` or panic if it the converted value wouldn't fit +help: you can convert an `u8` to `i64` and panic if the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -320,7 +320,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected i64, found isize -help: you can convert an `isize` to `i64` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `i64` and panic if the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -357,7 +357,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected u32, found usize -help: you can convert an `usize` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `u32` and panic if the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -367,7 +367,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected u32, found u64 -help: you can convert an `u64` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `u32` and panic if the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -395,7 +395,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected u32, found isize -help: you can convert an `isize` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `u32` and panic if the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -405,7 +405,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected u32, found i64 -help: you can convert an `i64` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `u32` and panic if the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -415,7 +415,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected u32, found i32 -help: you can convert an `i32` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `u32` and panic if the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -425,7 +425,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected u32, found i16 -help: you can convert an `i16` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `i16` to `u32` and panic if the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -435,7 +435,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected u32, found i8 -help: you can convert an `i8` to `u32` or panic if it the converted value wouldn't fit +help: you can convert an `i8` to `u32` and panic if the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -445,7 +445,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected i32, found usize -help: you can convert an `usize` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `i32` and panic if the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -455,7 +455,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected i32, found u64 -help: you can convert an `u64` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `i32` and panic if the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -465,7 +465,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected i32, found u32 -help: you can convert an `u32` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `i32` and panic if the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -475,7 +475,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected i32, found u16 -help: you can convert an `u16` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `i32` and panic if the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -485,7 +485,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected i32, found u8 -help: you can convert an `u8` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `u8` to `i32` and panic if the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -495,7 +495,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected i32, found isize -help: you can convert an `isize` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `i32` and panic if the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -505,7 +505,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected i32, found i64 -help: you can convert an `i64` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i32` and panic if the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -533,7 +533,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected u16, found usize -help: you can convert an `usize` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `u16` and panic if the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -543,7 +543,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected u16, found u64 -help: you can convert an `u64` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `u16` and panic if the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -553,7 +553,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected u16, found u32 -help: you can convert an `u32` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `u16` and panic if the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -572,7 +572,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected u16, found isize -help: you can convert an `isize` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `u16` and panic if the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -582,7 +582,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected u16, found i64 -help: you can convert an `i64` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `u16` and panic if the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -592,7 +592,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected u16, found i32 -help: you can convert an `i32` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `u16` and panic if the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -602,7 +602,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected u16, found i16 -help: you can convert an `i16` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `i16` to `u16` and panic if the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -612,7 +612,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected u16, found i8 -help: you can convert an `i8` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `i8` to `u16` and panic if the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -622,7 +622,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected i16, found usize -help: you can convert an `usize` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `i16` and panic if the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -632,7 +632,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected i16, found u64 -help: you can convert an `u64` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `i16` and panic if the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -642,7 +642,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected i16, found u32 -help: you can convert an `u32` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `i16` and panic if the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -652,7 +652,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected i16, found u16 -help: you can convert an `u16` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `i16` and panic if the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -662,7 +662,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected i16, found u8 -help: you can convert an `u8` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `u8` to `i16` and panic if the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -672,7 +672,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected i16, found isize -help: you can convert an `isize` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `i16` and panic if the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -682,7 +682,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected i16, found i64 -help: you can convert an `i64` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i16` and panic if the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -692,7 +692,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected i16, found i32 -help: you can convert an `i32` to `i16` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `i16` and panic if the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -711,7 +711,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected u8, found usize -help: you can convert an `usize` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `u8` and panic if the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -721,7 +721,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected u8, found u64 -help: you can convert an `u64` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `u8` and panic if the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -731,7 +731,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected u8, found u32 -help: you can convert an `u32` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `u8` and panic if the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -741,7 +741,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected u8, found u16 -help: you can convert an `u16` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `u8` and panic if the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -751,7 +751,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected u8, found isize -help: you can convert an `isize` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `u8` and panic if the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -761,7 +761,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected u8, found i64 -help: you can convert an `i64` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `u8` and panic if the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -771,7 +771,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected u8, found i32 -help: you can convert an `i32` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `u8` and panic if the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -781,7 +781,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected u8, found i16 -help: you can convert an `i16` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `i16` to `u8` and panic if the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -791,7 +791,7 @@ error[E0308]: mismatched types | LL | foo::(x_i8); | ^^^^ expected u8, found i8 -help: you can convert an `i8` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `i8` to `u8` and panic if the converted value wouldn't fit | LL | foo::(x_i8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -801,7 +801,7 @@ error[E0308]: mismatched types | LL | foo::(x_usize); | ^^^^^^^ expected i8, found usize -help: you can convert an `usize` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `usize` to `i8` and panic if the converted value wouldn't fit | LL | foo::(x_usize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -811,7 +811,7 @@ error[E0308]: mismatched types | LL | foo::(x_u64); | ^^^^^ expected i8, found u64 -help: you can convert an `u64` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `u64` to `i8` and panic if the converted value wouldn't fit | LL | foo::(x_u64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -821,7 +821,7 @@ error[E0308]: mismatched types | LL | foo::(x_u32); | ^^^^^ expected i8, found u32 -help: you can convert an `u32` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `u32` to `i8` and panic if the converted value wouldn't fit | LL | foo::(x_u32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -831,7 +831,7 @@ error[E0308]: mismatched types | LL | foo::(x_u16); | ^^^^^ expected i8, found u16 -help: you can convert an `u16` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `u16` to `i8` and panic if the converted value wouldn't fit | LL | foo::(x_u16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -841,7 +841,7 @@ error[E0308]: mismatched types | LL | foo::(x_u8); | ^^^^ expected i8, found u8 -help: you can convert an `u8` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `u8` to `i8` and panic if the converted value wouldn't fit | LL | foo::(x_u8.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^ @@ -851,7 +851,7 @@ error[E0308]: mismatched types | LL | foo::(x_isize); | ^^^^^^^ expected i8, found isize -help: you can convert an `isize` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `i8` and panic if the converted value wouldn't fit | LL | foo::(x_isize.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -861,7 +861,7 @@ error[E0308]: mismatched types | LL | foo::(x_i64); | ^^^^^ expected i8, found i64 -help: you can convert an `i64` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i8` and panic if the converted value wouldn't fit | LL | foo::(x_i64.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -871,7 +871,7 @@ error[E0308]: mismatched types | LL | foo::(x_i32); | ^^^^^ expected i8, found i32 -help: you can convert an `i32` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `i8` and panic if the converted value wouldn't fit | LL | foo::(x_i32.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -881,7 +881,7 @@ error[E0308]: mismatched types | LL | foo::(x_i16); | ^^^^^ expected i8, found i16 -help: you can convert an `i16` to `i8` or panic if it the converted value wouldn't fit +help: you can convert an `i16` to `i8` and panic if the converted value wouldn't fit | LL | foo::(x_i16.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/pattern/const-pat-ice.stderr b/src/test/ui/pattern/const-pat-ice.stderr index fabaea0535f5b..c4f6e0212621f 100644 --- a/src/test/ui/pattern/const-pat-ice.stderr +++ b/src/test/ui/pattern/const-pat-ice.stderr @@ -1,5 +1,5 @@ thread 'rustc' panicked at 'assertion failed: rows.iter().all(|r| r.len() == v.len())', src/librustc_mir/hair/pattern/_match.rs:1085:5 -note: Run with `RUST_BACKTRACE=1` environment variable to display a backtrace. +note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace. error: internal compiler error: unexpected panic diff --git a/src/test/ui/pub/pub-restricted.stderr b/src/test/ui/pub/pub-restricted.stderr index 7eeefa9550543..596264ba16b42 100644 --- a/src/test/ui/pub/pub-restricted.stderr +++ b/src/test/ui/pub/pub-restricted.stderr @@ -21,7 +21,18 @@ LL | pub (b) fn bfn() {} `pub(in path::to::module)`: visible only on the specified path error[E0704]: incorrect visibility restriction - --> $DIR/pub-restricted.rs:22:14 + --> $DIR/pub-restricted.rs:7:6 + | +LL | pub (crate::a) fn cfn() {} + | ^^^^^^^^ help: make this visible only to module `crate::a` with `in`: `in crate::a` + | + = help: some possible visibility restrictions are: + `pub(crate)`: visible only on the current crate + `pub(super)`: visible only in the current module's parent + `pub(in path::to::module)`: visible only on the specified path + +error[E0704]: incorrect visibility restriction + --> $DIR/pub-restricted.rs:24:14 | LL | pub (a) invalid: usize, | ^ help: make this visible only to module `a` with `in`: `in a` @@ -32,7 +43,7 @@ LL | pub (a) invalid: usize, `pub(in path::to::module)`: visible only on the specified path error[E0704]: incorrect visibility restriction - --> $DIR/pub-restricted.rs:31:6 + --> $DIR/pub-restricted.rs:33:6 | LL | pub (xyz) fn xyz() {} | ^^^ help: make this visible only to module `xyz` with `in`: `in xyz` @@ -43,11 +54,11 @@ LL | pub (xyz) fn xyz() {} `pub(in path::to::module)`: visible only on the specified path error: visibilities can only be restricted to ancestor modules - --> $DIR/pub-restricted.rs:23:17 + --> $DIR/pub-restricted.rs:25:17 | LL | pub (in x) non_parent_invalid: usize, | ^ -error: aborting due to 5 previous errors +error: aborting due to 6 previous errors For more information about this error, try `rustc --explain E0704`. diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index 6772aa1c38d2c..df73ac0b182f0 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -42,7 +42,7 @@ error[E0308]: mismatched types | LL | let f = [0; -4_isize]; | ^^^^^^^^ expected usize, found isize -help: you can convert an `isize` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit | LL | let f = [0; (-4_isize).try_into().unwrap()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -52,7 +52,7 @@ error[E0308]: mismatched types | LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected usize, found isize -help: you can convert an `isize` to `usize` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit | LL | let f = [0_usize; (-1_isize).try_into().unwrap()]; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/shift-various-bad-types.stderr b/src/test/ui/shift-various-bad-types.stderr index 97523fe82cd4e..409fabb951adc 100644 --- a/src/test/ui/shift-various-bad-types.stderr +++ b/src/test/ui/shift-various-bad-types.stderr @@ -27,7 +27,7 @@ error[E0308]: mismatched types | LL | let _: i32 = 22_i64 >> 1_i32; | ^^^^^^^^^^^^^^^ expected i32, found i64 -help: you can convert an `i64` to `i32` or panic if it the converted value wouldn't fit +help: you can convert an `i64` to `i32` and panic if the converted value wouldn't fit | LL | let _: i32 = (22_i64 >> 1_i32).try_into().unwrap(); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/symbol-names/basic.stderr b/src/test/ui/symbol-names/basic.stderr index 6ddd93d632e15..7539cbada8b7b 100644 --- a/src/test/ui/symbol-names/basic.stderr +++ b/src/test/ui/symbol-names/basic.stderr @@ -1,4 +1,4 @@ -error: symbol-name(_ZN5basic4main17h08bcaf310214ed52E) +error: symbol-name(_ZN5basic4main17hd72940ef9669d526E) --> $DIR/basic.rs:3:1 | LL | #[rustc_symbol_name] diff --git a/src/test/ui/symbol-names/impl1.stderr b/src/test/ui/symbol-names/impl1.stderr index eda8646b5b4de..20e48782a3a9e 100644 --- a/src/test/ui/symbol-names/impl1.stderr +++ b/src/test/ui/symbol-names/impl1.stderr @@ -1,4 +1,4 @@ -error: symbol-name(_ZN5impl13foo3Foo3bar17hc487d6ec13fe9124E) +error: symbol-name(_ZN5impl13foo3Foo3bar17he53b9bee7600ed8dE) --> $DIR/impl1.rs:8:9 | LL | #[rustc_symbol_name] @@ -10,7 +10,7 @@ error: def-path(foo::Foo::bar) LL | #[rustc_def_path] | ^^^^^^^^^^^^^^^^^ -error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h38577281258e1527E) +error: symbol-name(_ZN5impl13bar33_$LT$impl$u20$impl1..foo..Foo$GT$3baz17h86c41f0462d901d4E) --> $DIR/impl1.rs:18:9 | LL | #[rustc_symbol_name] diff --git a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr index 9acd63c2c25f1..e9c28248044f9 100644 --- a/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr +++ b/src/test/ui/trivial-bounds/trivial-bounds-inconsistent-projection-error.stderr @@ -6,7 +6,7 @@ LL | fn global_bound_is_hidden() -> u8 ... LL | B::get_x() | ^^^^^^^^^^ expected u8, found i32 -help: you can convert an `i32` to `u8` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `u8` and panic if the converted value wouldn't fit | LL | B::get_x().try_into().unwrap() | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/src/test/ui/tutorial-suffix-inference-test.stderr b/src/test/ui/tutorial-suffix-inference-test.stderr index f51f2defd4759..f3e1cc41cada2 100644 --- a/src/test/ui/tutorial-suffix-inference-test.stderr +++ b/src/test/ui/tutorial-suffix-inference-test.stderr @@ -12,7 +12,7 @@ error[E0308]: mismatched types | LL | identity_u16(y); | ^ expected u16, found i32 -help: you can convert an `i32` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `i32` to `u16` and panic if the converted value wouldn't fit | LL | identity_u16(y.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^ @@ -22,7 +22,7 @@ error[E0308]: mismatched types | LL | identity_u16(a); | ^ expected u16, found isize -help: you can convert an `isize` to `u16` or panic if it the converted value wouldn't fit +help: you can convert an `isize` to `u16` and panic if the converted value wouldn't fit | LL | identity_u16(a.try_into().unwrap()); | ^^^^^^^^^^^^^^^^^^^^^ From 2cdd7f8387bf1dc08bbd1c11abd83cb1f892e6cd Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sun, 2 Jun 2019 19:31:55 +0100 Subject: [PATCH 15/24] Removed unnecessary nested-lifetime-bounds test. --- .../nested-lifetime-bounds.rs | 25 ------------------- .../nested-lifetime-bounds.stderr | 8 ------ 2 files changed, 33 deletions(-) delete mode 100644 src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs delete mode 100644 src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr diff --git a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs deleted file mode 100644 index 25c2c2916f3bc..0000000000000 --- a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.rs +++ /dev/null @@ -1,25 +0,0 @@ -// compile-fail - -#![feature(associated_type_bounds)] - -use std::fmt::Debug; - -trait Lam { type App; } - -fn nested_bounds<_0, _1, _2, D>() -where - D: Clone + Iterator Iterator Lam<&'a &'b u8, App = _0>>>, - //~^ ERROR nested quantification of lifetimes [E0316] - _0: Debug, -{} - -fn nested_bounds_desugared<_0, _1, _2, D>() -where - D: Clone + Iterator, - _2: Send + for<'a> Iterator, - for<'a> <_2 as Iterator>::Item: for<'b> Lam<&'a &'b u8, App = _0>, - //~^ ERROR nested quantification of lifetimes [E0316] - _0: Debug, -{} - -fn main() {} diff --git a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr b/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr deleted file mode 100644 index db421e6973d07..0000000000000 --- a/src/test/ui/associated-type-bounds/nested-lifetime-bounds.stderr +++ /dev/null @@ -1,8 +0,0 @@ -error[E0316]: nested quantification of lifetimes - --> $DIR/nested-lifetime-bounds.rs:20:37 - | -LL | for<'a> <_2 as Iterator>::Item: for<'b> Lam<&'a &'b u8, App = _0>, - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to previous error - From 963e22c38c97f342338b9d93ca5be58418fb535f Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 8 May 2019 15:58:42 -0400 Subject: [PATCH 16/24] added a few comments --- src/librustc_typeck/astconv.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 4a2949fa6b069..92c5df72d8c16 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -571,6 +571,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { /// Given the type/lifetime/const arguments provided to some path (along with /// an implicit `Self`, if this is a trait reference), returns the complete /// set of substitutions. This may involve applying defaulted type parameters. + /// Also returns back constriants on associated types. /// /// Note that the type listing given here is *exactly* what the user provided. fn create_substs_for_ast_path<'a>(&self, @@ -1091,6 +1092,10 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }), binding.span)); } ConvertedBindingKind::Constraint(ref ast_bounds) => { + // "Desugar" a constraint like `T: Iterator` to + // + // `::Item: Debug` + // // Calling `skip_binder` is okay, because the predicates are re-bound later by // `instantiate_poly_trait_ref`. let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs); From 049f4d8cf4bf5613a658316afbec168fc03294ba Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Wed, 5 Jun 2019 20:57:44 +0100 Subject: [PATCH 17/24] document the `Bounds` struct a bit --- src/librustc_typeck/astconv.rs | 39 ++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 92c5df72d8c16..2ba6601e82631 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -2287,17 +2287,52 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } } -// A helper struct for conveniently grouping a set of bounds which we pass to -// and return from functions in multiple places. +/// Collects together a list of bounds that are applied to some type, +/// after they've been converted into `ty` form (from the HIR +/// representations). These lists of bounds occur in many places in +/// Rust's syntax: +/// +/// ``` +/// trait Foo: Bar + Baz { } +/// ^^^^^^^^^ supertrait list bounding the `Self` type parameter +/// +/// fn foo() { } +/// ^^^^^^^^^ bounding the type parameter `T` +/// +/// impl dyn Bar + Baz +/// ^^^^^^^^^ bounding the forgotten dynamic type +/// ``` +/// +/// Our representation is a bit mixed here -- in some cases, we +/// include the self type (e.g., `trait_bounds`) but in others we do #[derive(Default, PartialEq, Eq, Clone, Debug)] pub struct Bounds<'tcx> { + /// A list of region bounds on the (implicit) self type. So if you + /// had `T: 'a + 'b` this might would be a list `['a, 'b]` (but + /// the `T` is not explicitly included). pub region_bounds: Vec<(ty::Region<'tcx>, Span)>, + + /// A list of trait bounds. So if you had `T: Debug` this would be + /// `T: Debug`. Note that the self-type is explicit here. pub trait_bounds: Vec<(ty::PolyTraitRef<'tcx>, Span)>, + + /// A list of projection equality bounds. So if you had `T: + /// Iterator` this would include `::Item => u32`. Note that the self-type is explicit + /// here. pub projection_bounds: Vec<(ty::PolyProjectionPredicate<'tcx>, Span)>, + + /// `Some` if there is *no* `?Sized` predicate. The `span` + /// is the location in the source of the `T` declaration which can + /// be cited as the source of the `T: Sized` requirement. pub implicitly_sized: Option, } impl<'a, 'gcx, 'tcx> Bounds<'tcx> { + /// Converts a bounds list into a flat set of predicates (like + /// where-clauses). Because some of our bounds listings (e.g., + /// regions) don't include the self-type, you must supply the + /// self-type here (the `param_ty` parameter). pub fn predicates(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, param_ty: Ty<'tcx>) -> Vec<(ty::Predicate<'tcx>, Span)> { From f6ee542f16785fd944a663b8f4bc203ad150d2de Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 31 May 2019 17:14:36 -0400 Subject: [PATCH 18/24] make `instantiate_poly_trait_ref_inner` private to this module From 83078f0b37fd944f09bcfce4f8d476814b936aae Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 31 May 2019 17:15:15 -0400 Subject: [PATCH 19/24] comment `instantiate_poly_trait_ref` and its binder behavior --- src/librustc_typeck/astconv.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 2ba6601e82631..28c5c13492aac 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -792,6 +792,25 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { (poly_trait_ref, potential_assoc_types) } + /// Given a trait bound like `Debug`, applies that trait bound the given self-type to construct + /// a full trait reference. The resulting trait reference is returned. This may also generate + /// auxiliary bounds, which are added to `bounds`. + /// + /// Example: + /// + /// ``` + /// poly_trait_ref = Iterator + /// self_ty = Foo + /// ``` + /// + /// this would return `Foo: Iterator` and add `::Item = u32` into `bounds`. + /// + /// **A note on binders:** against our usual convention, there is an implied bounder around + /// the `self_ty` and `poly_trait_ref` parameters here. So they may reference bound regions. + /// If for example you had `for<'a> Foo<'a>: Bar<'a>`, then the `self_ty` would be `Foo<'a>` + /// where `'a` is a bound region at depth 0. Similarly, the `poly_trait_ref` would be + /// `Bar<'a>`. The returned poly-trait-ref will have this binder instantiated explicitly, + /// however. pub fn instantiate_poly_trait_ref(&self, poly_trait_ref: &hir::PolyTraitRef, self_ty: Ty<'tcx>, From 18d5085bff5680fcd1027722ebaf71703384eb33 Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 31 May 2019 17:30:44 -0400 Subject: [PATCH 20/24] more comments --- src/librustc_typeck/astconv.rs | 34 +++++++++++++++++++++++++++++++--- 1 file changed, 31 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 28c5c13492aac..5873d0fe8229f 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -929,6 +929,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { true } + /// This helper takes a *converted* parameter type (`param_ty`) + /// and an *unconverted* list of bounds: + /// + /// ``` + /// fn foo + /// ^ ^^^^^ `ast_bounds` parameter, in HIR form + /// | + /// `param_ty`, in ty form + /// ``` + /// + /// It adds these `ast_bounds` into the `bounds` structure. + /// + /// **A note on binders:** There is an implied binder around + /// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref` + /// for more details. fn add_bounds(&self, param_ty: Ty<'tcx>, ast_bounds: &[hir::GenericBound], @@ -962,9 +977,22 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { ); } - /// Translates the AST's notion of ty param bounds (which are an enum consisting of a newtyped - /// `Ty` or a region) to ty's notion of ty param bounds (which can either be user-defined traits - /// or the built-in trait `Sized`). + /// Translates a list of bounds from the HIR into the `Bounds` data structure. + /// The self-type for the bounds is given by `param_ty`. + /// + /// Example: + /// + /// ``` + /// fn foo() { } + /// ^ ^^^^^^^^^ ast_bounds + /// param_ty + /// ``` + /// + /// The `sized_by_default` parameter indicates if, in this context, the `param_ty` should be + /// considered `Sized` unless there is an explicit `?Sized` bound. This would be true in the + /// example above, but is not true in supertrait listings like `trait Foo: Bar + Baz`. + /// + /// `span` should be the declaration size of the parameter. pub fn compute_bounds(&self, param_ty: Ty<'tcx>, ast_bounds: &[hir::GenericBound], From e48dd1257c54dda498f02ce7823b6d7fbf24c36a Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 5 Jun 2019 15:20:40 -0400 Subject: [PATCH 21/24] another comment --- src/librustc_typeck/astconv.rs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 5873d0fe8229f..fc93d7ee61326 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -941,7 +941,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { /// /// It adds these `ast_bounds` into the `bounds` structure. /// - /// **A note on binders:** There is an implied binder around + /// **A note on binders:** there is an implied binder around /// `param_ty` and `ast_bounds`. See `instantiate_poly_trait_ref` /// for more details. fn add_bounds(&self, @@ -1017,6 +1017,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { bounds } + /// Given an HIR binding like `Item = Foo` or `Item: Foo`, pushes the corresponding predicates + /// onto `bounds`. + /// + /// **A note on binders:** given something like `T: for<'a> Iterator`, the + /// `trait_ref` here will be `for<'a> T: Iterator`. The `binding` data however is from *inside* + /// the binder (e.g., `&'a u32`) and hence may reference bound regions. fn add_predicates_for_ast_type_binding( &self, hir_ref_id: hir::HirId, From a90042718848e25a7df29621592250ccecf78b4d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Wed, 5 Jun 2019 15:27:19 -0400 Subject: [PATCH 22/24] verified that skip-binder is ok --- src/librustc_typeck/astconv.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index fc93d7ee61326..7f2d3c8e424b9 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1149,8 +1149,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // // `::Item: Debug` // - // Calling `skip_binder` is okay, because the predicates are re-bound later by - // `instantiate_poly_trait_ref`. + // Calling `skip_binder` is okay, because `add_bounds` expects the `param_ty` + // parameter to have a skipped binder. let param_ty = tcx.mk_projection(assoc_ty.def_id, candidate.skip_binder().substs); self.add_bounds( param_ty, From e37a7a1f74afb0b62b933af4439d271f4b8f890a Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Wed, 5 Jun 2019 21:08:36 +0100 Subject: [PATCH 23/24] add an example to `create_substs_for_ast_path` --- src/librustc_typeck/astconv.rs | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 7f2d3c8e424b9..34f817ba570e7 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -573,6 +573,20 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { /// set of substitutions. This may involve applying defaulted type parameters. /// Also returns back constriants on associated types. /// + /// Example: + /// + /// ``` + /// T: std::ops::Index + /// ^1 ^^^^^^^^^^^^^^2 ^^^^3 ^^^^^^^^^^^4 + /// ``` + /// + /// 1. The `self_ty` here would refer to the type `T`. + /// 2. The path in question is the path to the trait `std::ops::Index`, + /// which will have been resolved to a `def_id` + /// 3. The `generic_args` contains info on the `<...>` contents. The `usize` type + /// parameters are returned in the `SubstsRef`, the associated type bindings like + /// `Output = u32` are returned in the `Vec` result. + /// /// Note that the type listing given here is *exactly* what the user provided. fn create_substs_for_ast_path<'a>(&self, span: Span, From ee890331f6e33afe12ef250eb6388db2aab7cbbf Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 6 Jun 2019 03:28:53 +0100 Subject: [PATCH 24/24] Reblessed tests with NLL compare mode on. --- .../implied-region-constraints.nll.stderr | 24 +++++++++++++++++++ ...t_outlive_least_region_or_bound.nll.stderr | 4 ++-- .../static-return-lifetime-infered.nll.stderr | 4 ++-- 3 files changed, 28 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr diff --git a/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr b/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr new file mode 100644 index 0000000000000..32d099fce759e --- /dev/null +++ b/src/test/ui/associated-type-bounds/implied-region-constraints.nll.stderr @@ -0,0 +1,24 @@ +error: lifetime may not live long enough + --> $DIR/implied-region-constraints.rs:19:56 + | +LL | fn _bad_st<'a, 'b, T>(x: St<'a, 'b, T>) + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x.f0; + | ^^^^^ type annotation requires that `'a` must outlive `'b` + +error: lifetime may not live long enough + --> $DIR/implied-region-constraints.rs:40:64 + | +LL | fn _bad_en7<'a, 'b, T>(x: En7<'a, 'b, T>) + | -- -- lifetime `'b` defined here + | | + | lifetime `'a` defined here +... +LL | let _failure_proves_not_implied_outlives_region_b: &'b T = &x; + | ^^^^^ type annotation requires that `'a` must outlive `'b` + +error: aborting due to 2 previous errors + diff --git a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr index 4b7c04f1e4331..b1e4edd998094 100644 --- a/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr +++ b/src/test/ui/impl-trait/must_outlive_least_region_or_bound.nll.stderr @@ -5,7 +5,7 @@ LL | fn elided(x: &i32) -> impl Copy { x } | - ^^^^^^^^^ opaque type requires that `'1` must outlive `'static` | | | let's call the lifetime of this reference `'1` -help: to allow this impl Trait to capture borrowed data with lifetime `'1`, add `'_` as a constraint +help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint | LL | fn elided(x: &i32) -> impl Copy + '_ { x } | ^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn explicit<'a>(x: &'a i32) -> impl Copy { x } | -- ^^^^^^^^^ opaque type requires that `'a` must outlive `'static` | | | lifetime `'a` defined here -help: to allow this impl Trait to capture borrowed data with lifetime `'a`, add `'a` as a constraint +help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a constraint | LL | fn explicit<'a>(x: &'a i32) -> impl Copy + 'a { x } | ^^^^^^^^^^^^^^ diff --git a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr index 0bf120cf7ecc1..0736f25cb51bd 100644 --- a/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr +++ b/src/test/ui/impl-trait/static-return-lifetime-infered.nll.stderr @@ -5,7 +5,7 @@ LL | fn iter_values_anon(&self) -> impl Iterator { | - ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'1` must outlive `'static` | | | let's call the lifetime of this reference `'1` -help: to allow this impl Trait to capture borrowed data with lifetime `'1`, add `'_` as a constraint +help: to allow this `impl Trait` to capture borrowed data with lifetime `'1`, add `'_` as a constraint | LL | fn iter_values_anon(&self) -> impl Iterator + '_ { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -17,7 +17,7 @@ LL | fn iter_values<'a>(&'a self) -> impl Iterator { | -- ^^^^^^^^^^^^^^^^^^^^^^^ opaque type requires that `'a` must outlive `'static` | | | lifetime `'a` defined here -help: to allow this impl Trait to capture borrowed data with lifetime `'a`, add `'a` as a constraint +help: to allow this `impl Trait` to capture borrowed data with lifetime `'a`, add `'a` as a constraint | LL | fn iter_values<'a>(&'a self) -> impl Iterator + 'a { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^