From 1b150c4043654f93fcf7250b560581d44fc2b43d Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 1 Dec 2018 02:47:08 +0000 Subject: [PATCH 01/22] Store `Ident` rather than just `Name` in HIR types `Item` and `ForeignItem`. --- src/libproc_macro/bridge/rpc.rs | 2 +- src/librustc/hir/intravisit.rs | 13 ++--- src/librustc/hir/lowering.rs | 54 +++++++++---------- src/librustc/hir/map/blocks.rs | 2 +- src/librustc/hir/map/mod.rs | 16 +++--- src/librustc/hir/mod.rs | 6 +-- src/librustc/hir/print.rs | 37 ++++++------- src/librustc/ich/impls_hir.rs | 8 +-- src/librustc/middle/dead.rs | 6 +-- src/librustc/middle/entry.rs | 2 +- src/librustc/mir/mod.rs | 2 +- src/librustc/ty/layout.rs | 10 ++-- src/librustc/ty/mod.rs | 12 ++--- .../debuginfo/metadata.rs | 12 ++--- src/librustc_codegen_llvm/type_of.rs | 2 +- src/librustc_driver/test.rs | 2 +- src/librustc_lint/nonstandard_style.rs | 8 +-- src/librustc_lint/types.rs | 2 +- src/librustc_metadata/decoder.rs | 2 +- src/librustc_mir/hair/pattern/check_match.rs | 2 +- src/librustc_mir/hair/pattern/mod.rs | 2 +- src/librustc_mir/interpret/validity.rs | 2 +- src/librustc_resolve/macros.rs | 2 +- src/librustc_typeck/astconv.rs | 4 +- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/intrinsic.rs | 4 +- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustc_typeck/check/mod.rs | 10 ++-- src/librustc_typeck/check_unused.rs | 8 +-- src/librustc_typeck/collect.rs | 19 +++---- src/librustdoc/clean/mod.rs | 15 ++++-- .../passes/collect_intra_doc_links.rs | 2 +- src/librustdoc/test.rs | 6 +-- src/librustdoc/visit_ast.rs | 40 +++++++------- .../auxiliary/lint_group_plugin_test.rs | 51 ++++++++++++++++++ .../auxiliary/lint_group_plugin_test.rs | 4 +- src/test/ui-fulldeps/lint-group-plugin.rs | 1 + src/test/ui-fulldeps/lint-group-plugin.stderr | 4 +- 38 files changed, 221 insertions(+), 157 deletions(-) create mode 100644 src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs diff --git a/src/libproc_macro/bridge/rpc.rs b/src/libproc_macro/bridge/rpc.rs index ed5136462cf3d..6685aa1acac39 100644 --- a/src/libproc_macro/bridge/rpc.rs +++ b/src/libproc_macro/bridge/rpc.rs @@ -1,4 +1,4 @@ -//! Serialization for client<->server communication. +//! Serialization for client-server communication. use std::any::Any; use std::char; diff --git a/src/librustc/hir/intravisit.rs b/src/librustc/hir/intravisit.rs index 17b001a5ce8ac..d6b94052d1d5e 100644 --- a/src/librustc/hir/intravisit.rs +++ b/src/librustc/hir/intravisit.rs @@ -454,7 +454,7 @@ pub fn walk_trait_ref<'v, V>(visitor: &mut V, trait_ref: &'v TraitRef) pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_vis(&item.vis); - visitor.visit_name(item.span, item.name); + visitor.visit_ident(item.ident); match item.node { ItemKind::ExternCrate(orig_name) => { visitor.visit_id(item.id); @@ -472,7 +472,7 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { visitor.visit_nested_body(body); } ItemKind::Fn(ref declaration, header, ref generics, body_id) => { - visitor.visit_fn(FnKind::ItemFn(item.name, + visitor.visit_fn(FnKind::ItemFn(item.ident.name, generics, header, &item.vis, @@ -528,7 +528,8 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) { ItemKind::Union(ref struct_definition, ref generics) => { visitor.visit_generics(generics); visitor.visit_id(item.id); - visitor.visit_variant_data(struct_definition, item.name, generics, item.id, item.span); + visitor.visit_variant_data(struct_definition, item.ident.name, generics, item.id, + item.span); } ItemKind::Trait(.., ref generics, ref bounds, ref trait_item_refs) => { visitor.visit_id(item.id); @@ -569,9 +570,9 @@ pub fn walk_variant<'v, V: Visitor<'v>>(visitor: &mut V, variant: &'v Variant, generics: &'v Generics, parent_item_id: NodeId) { - visitor.visit_name(variant.span, variant.node.name); + visitor.visit_ident(variant.node.ident); visitor.visit_variant_data(&variant.node.data, - variant.node.name, + variant.node.ident.name, generics, parent_item_id, variant.span); @@ -720,7 +721,7 @@ pub fn walk_pat<'v, V: Visitor<'v>>(visitor: &mut V, pattern: &'v Pat) { pub fn walk_foreign_item<'v, V: Visitor<'v>>(visitor: &mut V, foreign_item: &'v ForeignItem) { visitor.visit_id(foreign_item.id); visitor.visit_vis(&foreign_item.vis); - visitor.visit_name(foreign_item.span, foreign_item.name); + visitor.visit_ident(foreign_item.ident); match foreign_item.node { ForeignItemKind::Fn(ref function_declaration, ref param_names, ref generics) => { diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 039b525c8644a..545a5024c5288 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1360,7 +1360,7 @@ impl<'a> LoweringContext<'a> { let exist_ty_item = hir::Item { id: exist_ty_id.node_id, hir_id: exist_ty_id.hir_id, - name: keywords::Invalid.name(), + ident: keywords::Invalid.ident(), attrs: Default::default(), node: exist_ty_item_kind, vis: respan(span.shrink_to_lo(), hir::VisibilityKind::Inherited), @@ -1563,7 +1563,7 @@ impl<'a> LoweringContext<'a> { fn lower_variant(&mut self, v: &Variant) -> hir::Variant { Spanned { node: hir::VariantKind { - name: v.node.ident.name, + ident: v.node.ident, attrs: self.lower_attrs(&v.node.attrs), data: self.lower_variant_data(&v.node.data), disr_expr: v.node.disr_expr.as_ref().map(|e| self.lower_anon_const(e)), @@ -2738,7 +2738,7 @@ impl<'a> LoweringContext<'a> { fn lower_item_kind( &mut self, id: NodeId, - name: &mut Name, + ident: &mut Ident, attrs: &hir::HirVec, vis: &mut hir::Visibility, i: &ItemKind, @@ -2752,7 +2752,7 @@ impl<'a> LoweringContext<'a> { span: use_tree.span, }; - self.lower_use_tree(use_tree, &prefix, id, vis, name, attrs) + self.lower_use_tree(use_tree, &prefix, id, vis, ident, attrs) } ItemKind::Static(ref t, m, ref e) => { let value = self.lower_body(None, |this| this.lower_expr(e)); @@ -2944,7 +2944,7 @@ impl<'a> LoweringContext<'a> { prefix: &Path, id: NodeId, vis: &mut hir::Visibility, - name: &mut Name, + ident: &mut Ident, attrs: &hir::HirVec, ) -> hir::ItemKind { debug!("lower_use_tree(tree={:?})", tree); @@ -2960,28 +2960,28 @@ impl<'a> LoweringContext<'a> { match tree.kind { UseTreeKind::Simple(rename, id1, id2) => { - *name = tree.ident().name; + *ident = tree.ident(); - // First apply the prefix to the path + // First, apply the prefix to the path. let mut path = Path { segments, span: path.span, }; - // Correctly resolve `self` imports + // Correctly resolve `self` imports. if path.segments.len() > 1 && path.segments.last().unwrap().ident.name == keywords::SelfLower.name() { let _ = path.segments.pop(); if rename.is_none() { - *name = path.segments.last().unwrap().ident.name; + *ident = path.segments.last().unwrap().ident; } } let parent_def_index = self.current_hir_id_owner.last().unwrap().0; let mut defs = self.expect_full_def_from_use(id); - // we want to return *something* from this function, so hang onto the first item - // for later + // We want to return *something* from this function, so hold onto the first item + // for later. let ret_def = defs.next().unwrap_or(Def::Err); // Here, we are looping over namespaces, if they exist for the definition @@ -2991,7 +2991,7 @@ impl<'a> LoweringContext<'a> { // two imports. for (def, &new_node_id) in defs.zip([id1, id2].iter()) { let vis = vis.clone(); - let name = name.clone(); + let ident = ident.clone(); let mut path = path.clone(); for seg in &mut path.segments { seg.id = self.sess.next_node_id(); @@ -3032,7 +3032,7 @@ impl<'a> LoweringContext<'a> { hir::Item { id: new_id.node_id, hir_id: new_id.hir_id, - name: name, + ident, attrs: attrs.clone(), node: item, vis, @@ -3058,8 +3058,8 @@ impl<'a> LoweringContext<'a> { hir::ItemKind::Use(path, hir::UseKind::Glob) } UseTreeKind::Nested(ref trees) => { - // Nested imports are desugared into simple - // imports. So if we start with + // Nested imports are desugared into simple imports. + // So, if we start with // // ``` // pub(x) use foo::{a, b}; @@ -3080,14 +3080,14 @@ impl<'a> LoweringContext<'a> { // `self.items`. However, the structure of this // function also requires us to return one item, and // for that we return the `{}` import (called the - // "`ListStem`"). + // `ListStem`). let prefix = Path { segments, span: prefix.span.to(path.span), }; - // Add all the nested PathListItems to the HIR. + // Add all the nested `PathListItem`s to the HIR. for &(ref use_tree, id) in trees { self.allocate_hir_id_counter(id, &use_tree); @@ -3097,10 +3097,10 @@ impl<'a> LoweringContext<'a> { } = self.lower_node_id(id); let mut vis = vis.clone(); - let mut name = name.clone(); + let mut ident = ident.clone(); let mut prefix = prefix.clone(); - // Give the segments new ids since they are being cloned. + // Give the segments new node-ids since they are being cloned. for seg in &mut prefix.segments { seg.id = self.sess.next_node_id(); } @@ -3115,7 +3115,7 @@ impl<'a> LoweringContext<'a> { &prefix, new_id, &mut vis, - &mut name, + &mut ident, attrs); let vis_kind = match vis.node { @@ -3139,7 +3139,7 @@ impl<'a> LoweringContext<'a> { hir::Item { id: new_id, hir_id: new_hir_id, - name, + ident, attrs: attrs.clone(), node: item, vis, @@ -3166,7 +3166,7 @@ impl<'a> LoweringContext<'a> { *vis = respan(prefix.span.shrink_to_lo(), hir::VisibilityKind::Inherited); } hir::VisibilityKind::Restricted { .. } => { - // do nothing here, as described in the comment on the match + // Do nothing here, as described in the comment on the match. } } @@ -3414,7 +3414,7 @@ impl<'a> LoweringContext<'a> { } pub fn lower_item(&mut self, i: &Item) -> Option { - let mut name = i.ident.name; + let mut ident = i.ident; let mut vis = self.lower_visibility(&i.vis, None); let attrs = self.lower_attrs(&i.attrs); if let ItemKind::MacroDef(ref def) = i.node { @@ -3422,7 +3422,7 @@ impl<'a> LoweringContext<'a> { attr::contains_name(&i.attrs, "rustc_doc_only_macro") { let body = self.lower_token_stream(def.stream()); self.exported_macros.push(hir::MacroDef { - name, + name: ident.name, vis, attrs, id: i.id, @@ -3434,14 +3434,14 @@ impl<'a> LoweringContext<'a> { return None; } - let node = self.lower_item_kind(i.id, &mut name, &attrs, &mut vis, &i.node); + let node = self.lower_item_kind(i.id, &mut ident, &attrs, &mut vis, &i.node); let LoweredNodeId { node_id, hir_id } = self.lower_node_id(i.id); Some(hir::Item { id: node_id, hir_id, - name, + ident, attrs, node, vis, @@ -3454,7 +3454,7 @@ impl<'a> LoweringContext<'a> { let def_id = self.resolver.definitions().local_def_id(node_id); hir::ForeignItem { id: node_id, - name: i.ident.name, + ident: i.ident, attrs: self.lower_attrs(&i.attrs), node: match i.node { ForeignItemKind::Fn(ref fdec, ref generics) => { diff --git a/src/librustc/hir/map/blocks.rs b/src/librustc/hir/map/blocks.rs index 895e1e782ab6e..837a20ac0f2f0 100644 --- a/src/librustc/hir/map/blocks.rs +++ b/src/librustc/hir/map/blocks.rs @@ -228,7 +228,7 @@ impl<'a> FnLikeNode<'a> { ast::ItemKind::Fn(ref decl, header, ref generics, block) => item_fn(ItemFnParts { id: i.id, - name: i.name, + name: i.ident.name, decl: &decl, body: block, vis: &i.vis, diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index d7c51f1e5fd36..188d487d64485 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -813,11 +813,11 @@ impl<'hir> Map<'hir> { /// Returns the name associated with the given NodeId's AST. pub fn name(&self, id: NodeId) -> Name { match self.get(id) { - Node::Item(i) => i.name, - Node::ForeignItem(i) => i.name, + Node::Item(i) => i.ident.name, + Node::ForeignItem(fi) => fi.ident.name, Node::ImplItem(ii) => ii.ident.name, Node::TraitItem(ti) => ti.ident.name, - Node::Variant(v) => v.node.name, + Node::Variant(v) => v.node.ident.name, Node::Field(f) => f.ident.name, Node::Lifetime(lt) => lt.name.ident().name, Node::GenericParam(param) => param.name.ident().name, @@ -953,7 +953,7 @@ impl<'a, 'hir> NodesMatchingSuffix<'a, 'hir> { loop { if let Node::Item(item) = map.find(id)? { if item_is_mod(&item) { - return Some((id, item.name)) + return Some((id, item.ident.name)) } } let parent = map.get_parent(id); @@ -1009,9 +1009,9 @@ trait Named { impl Named for Spanned { fn name(&self) -> Name { self.node.name() } } -impl Named for Item { fn name(&self) -> Name { self.name } } -impl Named for ForeignItem { fn name(&self) -> Name { self.name } } -impl Named for VariantKind { fn name(&self) -> Name { self.name } } +impl Named for Item { fn name(&self) -> Name { self.ident.name } } +impl Named for ForeignItem { fn name(&self) -> Name { self.ident.name } } +impl Named for VariantKind { fn name(&self) -> Name { self.ident.name } } impl Named for StructField { fn name(&self) -> Name { self.ident.name } } impl Named for TraitItem { fn name(&self) -> Name { self.ident.name } } impl Named for ImplItem { fn name(&self) -> Name { self.ident.name } } @@ -1194,7 +1194,7 @@ fn node_id_to_string(map: &Map<'_>, id: NodeId, include_id: bool) -> String { } Some(Node::Variant(ref variant)) => { format!("variant {} in {}{}", - variant.node.name, + variant.node.ident, path_str(), id_str) } Some(Node::Field(ref field)) => { diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 30817433823a8..f92ac4f74c3d7 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -2015,7 +2015,7 @@ pub struct EnumDef { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct VariantKind { - pub name: Name, + pub ident: Ident, pub attrs: HirVec, pub data: VariantData, /// Explicit discriminant, e.g., `Foo = 1` @@ -2176,7 +2176,7 @@ pub struct ItemId { /// The name might be a dummy name in case of anonymous items #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct Item { - pub name: Name, + pub ident: Ident, pub id: NodeId, pub hir_id: HirId, pub attrs: HirVec, @@ -2331,7 +2331,7 @@ pub enum AssociatedItemKind { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct ForeignItem { - pub name: Name, + pub ident: Ident, pub attrs: HirVec, pub node: ForeignItemKind, pub id: NodeId, diff --git a/src/librustc/hir/print.rs b/src/librustc/hir/print.rs index 9c869998d54f4..423dbab879d2d 100644 --- a/src/librustc/hir/print.rs +++ b/src/librustc/hir/print.rs @@ -450,7 +450,7 @@ impl<'a> State<'a> { abi: Abi::Rust, asyncness: hir::IsAsync::NotAsync, }, - Some(item.name), + Some(item.ident.name), generics, &item.vis, arg_names, @@ -464,7 +464,7 @@ impl<'a> State<'a> { if m { self.word_space("mut")?; } - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.word_space(":")?; self.print_type(&t)?; self.s.word(";")?; @@ -473,7 +473,7 @@ impl<'a> State<'a> { } hir::ForeignItemKind::Type => { self.head(visibility_qualified(&item.vis, "type"))?; - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.s.word(";")?; self.end()?; // end the head-ibox self.end() // end the outer cbox @@ -533,7 +533,7 @@ impl<'a> State<'a> { self.s.word("as")?; self.s.space()?; } - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.s.word(";")?; self.end()?; // end inner head-block self.end()?; // end outer head-block @@ -544,10 +544,10 @@ impl<'a> State<'a> { match kind { hir::UseKind::Single => { - if path.segments.last().unwrap().ident.name != item.name { + if path.segments.last().unwrap().ident != item.ident { self.s.space()?; self.word_space("as")?; - self.print_name(item.name)?; + self.print_ident(item.ident)?; } self.s.word(";")?; } @@ -562,7 +562,7 @@ impl<'a> State<'a> { if m == hir::MutMutable { self.word_space("mut")?; } - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.word_space(":")?; self.print_type(&ty)?; self.s.space()?; @@ -575,7 +575,7 @@ impl<'a> State<'a> { } hir::ItemKind::Const(ref ty, expr) => { self.head(visibility_qualified(&item.vis, "const"))?; - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.word_space(":")?; self.print_type(&ty)?; self.s.space()?; @@ -590,7 +590,7 @@ impl<'a> State<'a> { self.head("")?; self.print_fn(decl, header, - Some(item.name), + Some(item.ident.name), typarams, &item.vis, &[], @@ -602,7 +602,7 @@ impl<'a> State<'a> { } hir::ItemKind::Mod(ref _mod) => { self.head(visibility_qualified(&item.vis, "mod"))?; - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.nbsp()?; self.bopen()?; self.print_mod(_mod, &item.attrs)?; @@ -622,7 +622,7 @@ impl<'a> State<'a> { } hir::ItemKind::Ty(ref ty, ref generics) => { self.head(visibility_qualified(&item.vis, "type"))?; - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.print_generic_params(&generics.params)?; self.end()?; // end the inner ibox @@ -635,7 +635,7 @@ impl<'a> State<'a> { } hir::ItemKind::Existential(ref exist) => { self.head(visibility_qualified(&item.vis, "existential type"))?; - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.print_generic_params(&exist.generics.params)?; self.end()?; // end the inner ibox @@ -657,15 +657,16 @@ impl<'a> State<'a> { self.end()?; // end the outer ibox } hir::ItemKind::Enum(ref enum_definition, ref params) => { - self.print_enum_def(enum_definition, params, item.name, item.span, &item.vis)?; + self.print_enum_def(enum_definition, params, item.ident.name, item.span, + &item.vis)?; } hir::ItemKind::Struct(ref struct_def, ref generics) => { self.head(visibility_qualified(&item.vis, "struct"))?; - self.print_struct(struct_def, generics, item.name, item.span, true)?; + self.print_struct(struct_def, generics, item.ident.name, item.span, true)?; } hir::ItemKind::Union(ref struct_def, ref generics) => { self.head(visibility_qualified(&item.vis, "union"))?; - self.print_struct(struct_def, generics, item.name, item.span, true)?; + self.print_struct(struct_def, generics, item.ident.name, item.span, true)?; } hir::ItemKind::Impl(unsafety, polarity, @@ -712,7 +713,7 @@ impl<'a> State<'a> { self.print_is_auto(is_auto)?; self.print_unsafety(unsafety)?; self.word_nbsp("trait")?; - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.print_generic_params(&generics.params)?; let mut real_bounds = Vec::with_capacity(bounds.len()); for b in bounds.iter() { @@ -737,7 +738,7 @@ impl<'a> State<'a> { self.head("")?; self.print_visibility(&item.vis)?; self.word_nbsp("trait")?; - self.print_name(item.name)?; + self.print_ident(item.ident)?; self.print_generic_params(&generics.params)?; let mut real_bounds = Vec::with_capacity(bounds.len()); // FIXME(durka) this seems to be some quite outdated syntax @@ -895,7 +896,7 @@ impl<'a> State<'a> { pub fn print_variant(&mut self, v: &hir::Variant) -> io::Result<()> { self.head("")?; let generics = hir::Generics::empty(); - self.print_struct(&v.node.data, &generics, v.node.name, v.span, false)?; + self.print_struct(&v.node.data, &generics, v.node.ident.name, v.span, false)?; if let Some(ref d) = v.node.disr_expr { self.s.space()?; self.word_space("=")?; diff --git a/src/librustc/ich/impls_hir.rs b/src/librustc/ich/impls_hir.rs index f5d6827e89b49..9bf82baa68758 100644 --- a/src/librustc/ich/impls_hir.rs +++ b/src/librustc/ich/impls_hir.rs @@ -818,7 +818,7 @@ impl_stable_hash_for!(struct hir::EnumDef { }); impl_stable_hash_for!(struct hir::VariantKind { - name, + ident -> (ident.name), attrs, data, disr_expr @@ -852,7 +852,7 @@ impl<'a> HashStable> for hir::Item { hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { let hir::Item { - name, + ident, ref attrs, id: _, hir_id: _, @@ -862,7 +862,7 @@ impl<'a> HashStable> for hir::Item { } = *self; hcx.hash_hir_item_like(|hcx| { - name.hash_stable(hcx, hasher); + ident.name.hash_stable(hcx, hasher); attrs.hash_stable(hcx, hasher); node.hash_stable(hcx, hasher); vis.hash_stable(hcx, hasher); @@ -926,7 +926,7 @@ impl<'a> HashStable> for hir::AssociatedItemKind { } impl_stable_hash_for!(struct hir::ForeignItem { - name, + ident -> (ident.name), attrs, node, id, diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 3cc9bffa9a423..0c769c91801b8 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -557,7 +557,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { self.warn_dead_code( item.id, span, - item.name, + item.ident.name, item.node.descriptive_variant(), participle, ); @@ -572,7 +572,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { g: &'tcx hir::Generics, id: ast::NodeId) { if self.should_warn_about_variant(&variant.node) { - self.warn_dead_code(variant.node.data.id(), variant.span, variant.node.name, + self.warn_dead_code(variant.node.data.id(), variant.span, variant.node.ident.name, "variant", "constructed"); } else { intravisit::walk_variant(self, variant, g, id); @@ -581,7 +581,7 @@ impl<'a, 'tcx> Visitor<'tcx> for DeadVisitor<'a, 'tcx> { fn visit_foreign_item(&mut self, fi: &'tcx hir::ForeignItem) { if self.should_warn_about_foreign_item(fi) { - self.warn_dead_code(fi.id, fi.span, fi.name, + self.warn_dead_code(fi.id, fi.span, fi.ident.name, fi.node.descriptive_variant(), "used"); } intravisit::walk_foreign_item(self, fi); diff --git a/src/librustc/middle/entry.rs b/src/librustc/middle/entry.rs index 2add525f0940d..6b593a1a9f9b2 100644 --- a/src/librustc/middle/entry.rs +++ b/src/librustc/middle/entry.rs @@ -86,7 +86,7 @@ fn entry_point_type(item: &Item, at_root: bool) -> EntryPointType { EntryPointType::Start } else if attr::contains_name(&item.attrs, "main") { EntryPointType::MainAttr - } else if item.name == "main" { + } else if item.ident.name == "main" { if at_root { // This is a top-level function so can be 'main'. EntryPointType::MainNamed diff --git a/src/librustc/mir/mod.rs b/src/librustc/mir/mod.rs index f774b13f98301..36d51c5971278 100644 --- a/src/librustc/mir/mod.rs +++ b/src/librustc/mir/mod.rs @@ -2040,7 +2040,7 @@ impl<'tcx> Debug for Place<'tcx> { Promoted(ref promoted) => write!(fmt, "({:?}: {:?})", promoted.0, promoted.1), Projection(ref data) => match data.elem { ProjectionElem::Downcast(ref adt_def, index) => { - write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].name) + write!(fmt, "({:?} as {})", data.base, adt_def.variants[index].ident) } ProjectionElem::Deref => write!(fmt, "(*{:?})", data.base), ProjectionElem::Field(field, ty) => { diff --git a/src/librustc/ty/layout.rs b/src/librustc/ty/layout.rs index a5331cbbdb0e5..171c53b7b20ba 100644 --- a/src/librustc/ty/layout.rs +++ b/src/librustc/ty/layout.rs @@ -1,7 +1,7 @@ use session::{self, DataTypeKind}; use ty::{self, Ty, TyCtxt, TypeFoldable, ReprOptions}; -use syntax::ast::{self, IntTy, UintTy}; +use syntax::ast::{self, Ident, IntTy, UintTy}; use syntax::attr; use syntax_pos::DUMMY_SP; @@ -1228,7 +1228,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { let adt_kind = adt_def.adt_kind(); let adt_packed = adt_def.repr.packed(); - let build_variant_info = |n: Option, + let build_variant_info = |n: Option, flds: &[ast::Name], layout: TyLayout<'tcx>| { let mut min_size = Size::ZERO; @@ -1273,7 +1273,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { match layout.variants { Variants::Single { index } => { debug!("print-type-size `{:#?}` variant {}", - layout, adt_def.variants[index].name); + layout, adt_def.variants[index].ident); if !adt_def.variants.is_empty() { let variant_def = &adt_def.variants[index]; let fields: Vec<_> = @@ -1281,7 +1281,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { record(adt_kind.into(), adt_packed, None, - vec![build_variant_info(Some(variant_def.name), + vec![build_variant_info(Some(variant_def.ident), &fields, layout)]); } else { @@ -1299,7 +1299,7 @@ impl<'a, 'tcx> LayoutCx<'tcx, TyCtxt<'a, 'tcx, 'tcx>> { adt_def.variants.iter_enumerated().map(|(i, variant_def)| { let fields: Vec<_> = variant_def.fields.iter().map(|f| f.ident.name).collect(); - build_variant_info(Some(variant_def.name), + build_variant_info(Some(variant_def.ident), &fields, layout.for_variant(self, i)) }) diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 2256cd4364b70..b484e01567212 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -1773,7 +1773,7 @@ pub struct VariantDef { /// The variant's `DefId`. If this is a tuple-like struct, /// this is the `DefId` of the struct's ctor. pub did: DefId, - pub name: Name, // struct's name if this is a struct + pub ident: Ident, // struct's name if this is a struct pub discr: VariantDiscr, pub fields: Vec, pub ctor_kind: CtorKind, @@ -1797,7 +1797,7 @@ impl<'a, 'gcx, 'tcx> VariantDef { /// remove this hack and use the constructor DefId everywhere. pub fn new(tcx: TyCtxt<'a, 'gcx, 'tcx>, did: DefId, - name: Name, + ident: Ident, discr: VariantDiscr, fields: Vec, adt_kind: AdtKind, @@ -1805,7 +1805,7 @@ impl<'a, 'gcx, 'tcx> VariantDef { attribute_def_id: DefId) -> Self { - debug!("VariantDef::new({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?})", did, name, discr, + debug!("VariantDef::new({:?}, {:?}, {:?}, {:?}, {:?}, {:?}, {:?})", did, ident, discr, fields, adt_kind, ctor_kind, attribute_def_id); let mut flags = VariantFlags::NO_VARIANT_FLAGS; if adt_kind == AdtKind::Struct && tcx.has_attr(attribute_def_id, "non_exhaustive") { @@ -1814,7 +1814,7 @@ impl<'a, 'gcx, 'tcx> VariantDef { } VariantDef { did, - name, + ident, discr, fields, ctor_kind, @@ -1830,7 +1830,7 @@ impl<'a, 'gcx, 'tcx> VariantDef { impl_stable_hash_for!(struct VariantDef { did, - name, + ident -> (ident.name), discr, fields, ctor_kind, @@ -1971,8 +1971,6 @@ impl_stable_hash_for!(struct ReprFlags { bits }); - - /// Represents the repr options provided by the user, #[derive(Copy, Clone, Debug, Eq, PartialEq, RustcEncodable, RustcDecodable, Default)] pub struct ReprOptions { diff --git a/src/librustc_codegen_llvm/debuginfo/metadata.rs b/src/librustc_codegen_llvm/debuginfo/metadata.rs index 3be784ccc04b0..0fd04e9d20393 100644 --- a/src/librustc_codegen_llvm/debuginfo/metadata.rs +++ b/src/librustc_codegen_llvm/debuginfo/metadata.rs @@ -1215,7 +1215,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { name: if fallback { String::new() } else { - adt.variants[index].name.as_str().to_string() + adt.variants[index].ident.as_str().to_string() }, type_metadata: variant_type_metadata, offset: Size::ZERO, @@ -1255,7 +1255,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { name: if fallback { String::new() } else { - adt.variants[i].name.as_str().to_string() + adt.variants[i].ident.as_str().to_string() }, type_metadata: variant_type_metadata, offset: Size::ZERO, @@ -1321,7 +1321,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { self.layout, self.layout.fields.offset(0), self.layout.field(cx, 0).size); - name.push_str(&adt.variants[*niche_variants.start()].name.as_str()); + name.push_str(&adt.variants[*niche_variants.start()].ident.as_str()); // Create the (singleton) list of descriptions of union members. vec![ @@ -1365,7 +1365,7 @@ impl EnumMemberDescriptionFactory<'ll, 'tcx> { }; MemberDescription { - name: adt.variants[i].name.as_str().to_string(), + name: adt.variants[i].ident.as_str().to_string(), type_metadata: variant_type_metadata, offset: Size::ZERO, size: self.layout.size, @@ -1433,7 +1433,7 @@ fn describe_enum_variant( containing_scope: &'ll DIScope, span: Span, ) -> (&'ll DICompositeType, MemberDescriptionFactory<'ll, 'tcx>) { - let variant_name = variant.name.as_str(); + let variant_name = variant.ident.as_str(); let unique_type_id = debug_context(cx).type_map .borrow_mut() .get_unique_type_id_of_enum_variant( @@ -1527,7 +1527,7 @@ fn prepare_enum_metadata( let enumerators_metadata: Vec<_> = def.discriminants(cx.tcx) .zip(&def.variants) .map(|((_, discr), v)| { - let name = SmallCStr::new(&v.name.as_str()); + let name = SmallCStr::new(&v.ident.as_str()); unsafe { Some(llvm::LLVMRustDIBuilderCreateEnumerator( DIB(cx), diff --git a/src/librustc_codegen_llvm/type_of.rs b/src/librustc_codegen_llvm/type_of.rs index bac2294bd31c7..97128c2d2a2ce 100644 --- a/src/librustc_codegen_llvm/type_of.rs +++ b/src/librustc_codegen_llvm/type_of.rs @@ -60,7 +60,7 @@ fn uncached_llvm_type<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, = (&layout.ty.sty, &layout.variants) { if def.is_enum() && !def.variants.is_empty() { - write!(&mut name, "::{}", def.variants[index].name).unwrap(); + write!(&mut name, "::{}", def.variants[index].ident).unwrap(); } } Some(name) diff --git a/src/librustc_driver/test.rs b/src/librustc_driver/test.rs index a8cc401ac38ee..a5f7d676862e0 100644 --- a/src/librustc_driver/test.rs +++ b/src/librustc_driver/test.rs @@ -261,7 +261,7 @@ impl<'a, 'gcx, 'tcx> Env<'a, 'gcx, 'tcx> { assert!(idx < names.len()); for item in &m.item_ids { let item = this.infcx.tcx.hir().expect_item(item.id); - if item.name.to_string() == names[idx] { + if item.ident.to_string() == names[idx] { return search(this, item, idx + 1, names); } } diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index e425d2cdae9a7..2694a04b94ce4 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -278,7 +278,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { if let hir::ItemKind::Mod(_) = it.node { - self.check_snake_case(cx, "module", &it.name.as_str(), Some(it.span)); + self.check_snake_case(cx, "module", &it.ident.as_str(), Some(it.span)); } } @@ -354,10 +354,12 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonUpperCaseGlobals { if attr::find_by_name(&it.attrs, "no_mangle").is_some() { return; } - NonUpperCaseGlobals::check_upper_case(cx, "static variable", it.name, it.span); + NonUpperCaseGlobals::check_upper_case(cx, "static variable", it.ident.name, + it.span); } hir::ItemKind::Const(..) => { - NonUpperCaseGlobals::check_upper_case(cx, "constant", it.name, it.span); + NonUpperCaseGlobals::check_upper_case(cx, "constant", it.ident.name, + it.span); } _ => {} } diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index 65e1b9ff7628b..642681a73a8a0 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -837,7 +837,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for VariantSizeDifferences { let bytes = variant_layout.size.bytes().saturating_sub(discr_size); debug!("- variant `{}` is {} bytes large", - variant.node.name, + variant.node.ident, bytes); bytes }) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 687753bd8de08..dc8db5be5820a 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -553,7 +553,7 @@ impl<'a, 'tcx> CrateMetadata { ty::VariantDef::new( tcx, def_id, - self.item_name(index).as_symbol(), + Ident::from_interned_str(self.item_name(index)), data.discr, item.children.decode(self).map(|index| { let f = self.entry(index); diff --git a/src/librustc_mir/hair/pattern/check_match.rs b/src/librustc_mir/hair/pattern/check_match.rs index 50d861b674cef..f758e48887715 100644 --- a/src/librustc_mir/hair/pattern/check_match.rs +++ b/src/librustc_mir/hair/pattern/check_match.rs @@ -306,7 +306,7 @@ fn check_for_bindings_named_same_as_variants(cx: &MatchVisitor, pat: &Pat) { let pat_ty = cx.tables.pat_ty(p); if let ty::Adt(edef, _) = pat_ty.sty { if edef.is_enum() && edef.variants.iter().any(|variant| { - variant.name == ident.name && variant.ctor_kind == CtorKind::Const + variant.ident == ident && variant.ctor_kind == CtorKind::Const }) { let ty_path = cx.tcx.item_path_str(edef.did); let mut err = struct_span_warn!(cx.tcx.sess, p.span, E0170, diff --git a/src/librustc_mir/hair/pattern/mod.rs b/src/librustc_mir/hair/pattern/mod.rs index 92da0563d8091..62ec52aac1346 100644 --- a/src/librustc_mir/hair/pattern/mod.rs +++ b/src/librustc_mir/hair/pattern/mod.rs @@ -280,7 +280,7 @@ impl<'tcx> fmt::Display for Pattern<'tcx> { let mut start_or_continue = || if first { first = false; "" } else { ", " }; if let Some(variant) = variant { - write!(f, "{}", variant.name)?; + write!(f, "{}", variant.ident)?; // Only for Adt we can have `S {...}`, // which we handle separately here. diff --git a/src/librustc_mir/interpret/validity.rs b/src/librustc_mir/interpret/validity.rs index 5e006e20e4785..a5fb44587400a 100644 --- a/src/librustc_mir/interpret/validity.rs +++ b/src/librustc_mir/interpret/validity.rs @@ -246,7 +246,7 @@ impl<'rt, 'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> variant_id: VariantIdx, new_op: OpTy<'tcx, M::PointerTag> ) -> EvalResult<'tcx> { - let name = old_op.layout.ty.ty_adt_def().unwrap().variants[variant_id].name; + let name = old_op.layout.ty.ty_adt_def().unwrap().variants[variant_id].ident.name; self.visit_elem(new_op, PathElem::Variant(name)) } diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 98c6773cec323..a851d384d78f3 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -276,7 +276,7 @@ impl<'a> Resolver<'a> { let features = self.session.features_untracked(); if attr_kind == NonMacroAttrKind::Custom { assert!(path.segments.len() == 1); - let name = path.segments[0].ident.name.as_str(); + let name = path.segments[0].ident.as_str(); if name.starts_with("rustc_") { if !features.rustc_attrs { let msg = "unless otherwise specified, attributes with the prefix \ diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 736b416dd4f21..f33060dde4f15 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1322,8 +1322,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { span, &format!("no variant `{}` on enum `{}`", &assoc_name.as_str(), ty_str), ); - // Check if it was a typo - let input = adt_def.variants.iter().map(|variant| &variant.name); + // Check if it was a typo. + let input = adt_def.variants.iter().map(|variant| &variant.ident.name); if let Some(suggested_name) = find_best_match_for_name( input, &assoc_name.as_str(), diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index f227c529cb035..4e3cb5c7f1c0d 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -952,7 +952,7 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); if plural == "" { let input = unmentioned_fields.iter().map(|field| &field.name); let suggested_name = - find_best_match_for_name(input, &ident.name.as_str(), None); + find_best_match_for_name(input, &ident.as_str(), None); if let Some(suggested_name) = suggested_name { err.span_suggestion(*span, "did you mean", suggested_name.to_string()); // we don't want to throw `E0027` in case we have thrown `E0026` for them diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index c80990a0704bd..a36b21921436e 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -71,7 +71,7 @@ fn equate_intrinsic_type<'a, 'tcx>( pub fn check_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &hir::ForeignItem) { let param = |n| tcx.mk_ty_param(n, Symbol::intern(&format!("P{}", n)).as_interned_str()); - let name = it.name.as_str(); + let name = it.ident.as_str(); let mk_va_list_ty = || { tcx.lang_items().va_list().map(|did| { @@ -393,7 +393,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let def_id = tcx.hir().local_def_id(it.id); let i_n_tps = tcx.generics_of(def_id).own_counts().types; - let name = it.name.as_str(); + let name = it.ident.as_str(); let (n_tps, inputs, output) = match &*name { "simd_eq" | "simd_ne" | "simd_lt" | "simd_le" | "simd_gt" | "simd_ge" => { diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index c4a908d56f351..65a58d345ccfa 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -185,7 +185,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "method" } else if actual.is_enum() { if let Adt(ref adt_def, _) = actual.sty { - let names = adt_def.variants.iter().map(|s| &s.name); + let names = adt_def.variants.iter().map(|s| &s.ident.name); suggestion = find_best_match_for_name(names, &item_name.as_str(), None); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 15a9ba99fa711..414cc363f97a1 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1327,7 +1327,7 @@ pub fn check_item_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Ite } hir::ItemKind::Fn(..) => {} // entirely within check_item_body hir::ItemKind::Impl(.., ref impl_item_refs) => { - debug!("ItemKind::Impl {} with id {}", it.name, it.id); + debug!("ItemKind::Impl {} with id {}", it.ident, it.id); let impl_def_id = tcx.hir().local_def_id(it.id); if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) { check_impl_items_against_trait( @@ -3529,7 +3529,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty::Adt(adt, ..) if adt.is_enum() => { struct_span_err!(self.tcx.sess, field.ident.span, E0559, "{} `{}::{}` has no field named `{}`", - kind_name, actual, variant.name, field.ident) + kind_name, actual, variant.ident, field.ident) } _ => { struct_span_err!(self.tcx.sess, field.ident.span, E0560, @@ -3551,7 +3551,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if adt.is_enum() { err.span_label(field.ident.span, format!("`{}::{}` does not have this field", - ty, variant.name)); + ty, variant.ident)); } else { err.span_label(field.ident.span, format!("`{}` does not have this field", ty)); @@ -4813,13 +4813,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let parent = self.tcx.hir().get(fn_id); if let Node::Item(&hir::Item { - name, node: hir::ItemKind::Fn(ref decl, ..), .. + ident, node: hir::ItemKind::Fn(ref decl, ..), .. }) = parent { decl.clone().and_then(|decl| { // This is less than ideal, it will not suggest a return type span on any // method called `main`, regardless of whether it is actually the entry point, // but it will still present it as the reason for the expected type. - Some((decl, name != Symbol::intern("main"))) + Some((decl, ident.name != Symbol::intern("main"))) }) } else if let Node::TraitItem(&hir::TraitItem { node: hir::TraitItemKind::Method(hir::MethodSig { diff --git a/src/librustc_typeck/check_unused.rs b/src/librustc_typeck/check_unused.rs index 740e64b1895e8..bf767726ef715 100644 --- a/src/librustc_typeck/check_unused.rs +++ b/src/librustc_typeck/check_unused.rs @@ -154,7 +154,7 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { // If the extern crate isn't in the extern prelude, // there is no way it can be written as an `use`. - let orig_name = extern_crate.orig_name.unwrap_or(item.name); + let orig_name = extern_crate.orig_name.unwrap_or(item.ident.name); if !tcx.extern_prelude.get(&orig_name).map_or(false, |from_item| !from_item) { continue; } @@ -173,8 +173,8 @@ fn unused_crates_lint<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>) { visibility_qualified(&item.vis, "use") ); let base_replacement = match extern_crate.orig_name { - Some(orig_name) => format!("use {} as {};", orig_name, item.name), - None => format!("use {};", item.name), + Some(orig_name) => format!("use {} as {};", orig_name, item.ident.name), + None => format!("use {};", item.ident.name), }; let replacement = visibility_qualified(&item.vis, base_replacement); tcx.struct_span_lint_node(lint, id, extern_crate.span, msg) @@ -219,7 +219,7 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for CollectExternCrateVisitor<'a, 'tcx> { def_id: extern_crate_def_id, span: item.span, orig_name, - warn_if_unused: !item.name.as_str().starts_with('_'), + warn_if_unused: !item.ident.as_str().starts_with('_'), } ); } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index a46309c5ea14f..1aede7cf14c3c 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -33,7 +33,7 @@ use rustc_data_structures::sync::Lrc; use rustc_target::spec::abi; use syntax::ast; -use syntax::ast::MetaItemKind; +use syntax::ast::{Ident, MetaItemKind}; use syntax::attr::{InlineAttr, list_contains_name, mark_used}; use syntax::source_map::Spanned; use syntax::feature_gate; @@ -385,7 +385,7 @@ fn is_param<'a, 'tcx>( fn convert_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, item_id: ast::NodeId) { let it = tcx.hir().expect_item(item_id); - debug!("convert: item {} with id {}", it.name, it.id); + debug!("convert: item {} with id {}", it.ident, it.id); let def_id = tcx.hir().local_def_id(item_id); match it.node { // These don't define types. @@ -533,7 +533,7 @@ fn convert_enum_variant_types<'a, 'tcx>( format!("overflowed on value after {}", prev_discr.unwrap()), ).note(&format!( "explicitly set `{} = {}` if that is desired outcome", - variant.node.name, wrapped_discr + variant.node.ident, wrapped_discr )) .emit(); None @@ -556,7 +556,7 @@ fn convert_enum_variant_types<'a, 'tcx>( fn convert_variant<'a, 'tcx>( tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId, - name: ast::Name, + ident: Ident, discr: ty::VariantDiscr, def: &hir::VariantData, adt_kind: ty::AdtKind, @@ -593,12 +593,13 @@ fn convert_variant<'a, 'tcx>( .collect(); ty::VariantDef::new(tcx, did, - name, + ident, discr, fields, adt_kind, CtorKind::from_hir(def), - attribute_def_id) + attribute_def_id + ) } fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::AdtDef { @@ -628,7 +629,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad }; distance_from_explicit += 1; - convert_variant(tcx, did, v.node.name, discr, &v.node.data, AdtKind::Enum, + convert_variant(tcx, did, v.node.ident, discr, &v.node.data, AdtKind::Enum, did) }) .collect(), @@ -646,7 +647,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad std::iter::once(convert_variant( tcx, ctor_id.unwrap_or(def_id), - item.name, + item.ident, ty::VariantDiscr::Relative(0), def, AdtKind::Struct, @@ -659,7 +660,7 @@ fn adt_def<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> &'tcx ty::Ad std::iter::once(convert_variant( tcx, def_id, - item.name, + item.ident, ty::VariantDiscr::Relative(0), def, AdtKind::Union, diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 54d3e640ec585..38b2452b420e9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2967,7 +2967,7 @@ impl<'tcx> Clean for ty::VariantDef { } }; Item { - name: Some(self.name.clean(cx)), + name: Some(self.ident.clean(cx)), attrs: inline::load_attrs(cx, self.did), source: cx.tcx.def_span(self.did).clean(cx), visibility: Some(Inherited), @@ -3183,13 +3183,22 @@ fn qpath_to_string(p: &hir::QPath) -> String { s } +impl Clean for Ident { + #[inline] + fn clean(&self, cx: &DocContext) -> String { + self.name.clean(cx) + } +} + impl Clean for ast::Name { + #[inline] fn clean(&self, _: &DocContext) -> String { self.to_string() } } impl Clean for InternedString { + #[inline] fn clean(&self, _: &DocContext) -> String { self.to_string() } @@ -3616,7 +3625,7 @@ impl Clean for hir::ForeignItem { }; Item { - name: Some(self.name.clean(cx)), + name: Some(self.ident.clean(cx)), attrs: self.attrs.clean(cx), source: self.span.clean(cx), def_id: cx.tcx.hir().local_def_id(self.id), @@ -3951,7 +3960,7 @@ pub fn path_to_def_local(tcx: &TyCtxt, path: &[&str]) -> Option { for item_id in mem::replace(&mut items, HirVec::new()).iter() { let item = tcx.hir().expect_item(item_id.id); - if item.name == *segment { + if item.ident.name == *segment { if path_it.peek().is_none() { return Some(tcx.hir().local_def_id(item_id.id)) } diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index b8ec7e4bd32ab..fdc1c0616187a 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -632,7 +632,7 @@ fn handle_variant(cx: &DocContext, def: Def) -> Result<(Def, Option), () }; let parent_def = Def::Enum(parent); let variant = cx.tcx.expect_variant_def(def); - Ok((parent_def, Some(format!("{}.v", variant.name)))) + Ok((parent_def, Some(format!("{}.v", variant.ident.name)))) } const PRIMITIVES: &[(&str, Def)] = &[ diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 4d870daac4d03..24bb00f411242 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -811,7 +811,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { let name = if let hir::ItemKind::Impl(.., ref ty, _) = item.node { self.map.node_to_pretty_string(ty.id) } else { - item.name.to_string() + item.ident.to_string() }; self.visit_testable(name, &item.attrs, |this| { @@ -832,7 +832,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { } fn visit_foreign_item(&mut self, item: &'hir hir::ForeignItem) { - self.visit_testable(item.name.to_string(), &item.attrs, |this| { + self.visit_testable(item.ident.to_string(), &item.attrs, |this| { intravisit::walk_foreign_item(this, item); }); } @@ -841,7 +841,7 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { v: &'hir hir::Variant, g: &'hir hir::Generics, item_id: ast::NodeId) { - self.visit_testable(v.node.name.to_string(), &v.node.attrs, |this| { + self.visit_testable(v.node.ident.to_string(), &v.node.attrs, |this| { intravisit::walk_variant(this, v, g, item_id); }); } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index ffdc048a30ece..953ab7c2565bf 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -139,7 +139,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { Enum { name, variants: def.variants.iter().map(|v| Variant { - name: v.node.name, + name: v.node.ident.name, attrs: v.node.attrs.clone(), stab: self.stability(v.node.data.id()), depr: self.deprecation(v.node.data.id()), @@ -263,7 +263,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { fn maybe_inline_local(&mut self, id: ast::NodeId, def: Def, - renamed: Option, + renamed: Option, glob: bool, om: &mut Module, please_inline: bool) -> bool { @@ -357,14 +357,14 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { om.foreigns.push(hir::ForeignMod { abi: tcx.hir().get_foreign_abi(it.id), items: vec![hir::ForeignItem { - name: renamed.unwrap_or(it.name), + ident: renamed.unwrap_or(it.ident), .. it.clone() }].into(), }); true } Node::MacroDef(def) if !glob => { - om.macros.push(self.visit_local_macro(def, renamed)); + om.macros.push(self.visit_local_macro(def, renamed.map(|i| i.name))); true } _ => false, @@ -374,9 +374,9 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { } pub fn visit_item(&mut self, item: &hir::Item, - renamed: Option, om: &mut Module) { + renamed: Option, om: &mut Module) { debug!("Visiting item {:?}", item); - let name = renamed.unwrap_or(item.name); + let ident = renamed.unwrap_or(item.ident); if item.vis.node.is_pub() { let def_id = self.cx.tcx.hir().local_def_id(item.id); @@ -403,7 +403,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { om.extern_crates.push(ExternCrate { cnum: self.cx.tcx.extern_mod_stmt_cnum(def_id) .unwrap_or(LOCAL_CRATE), - name, + name: ident.name, path: orig_name.map(|x|x.to_string()), vis: item.vis.clone(), attrs: item.attrs.clone(), @@ -433,10 +433,10 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { _ => false, } }); - let name = if is_glob { None } else { Some(name) }; + let ident = if is_glob { None } else { Some(ident) }; if self.maybe_inline_local(item.id, path.def, - name, + ident, is_glob, om, please_inline) { @@ -445,7 +445,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { } om.imports.push(Import { - name, + name: ident.name, id: item.id, vis: item.vis.clone(), attrs: item.attrs.clone(), @@ -460,21 +460,21 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { item.vis.clone(), item.id, m, - Some(name))); + Some(ident.name))); }, hir::ItemKind::Enum(ref ed, ref gen) => - om.enums.push(self.visit_enum_def(item, name, ed, gen)), + om.enums.push(self.visit_enum_def(item, ident.name, ed, gen)), hir::ItemKind::Struct(ref sd, ref gen) => - om.structs.push(self.visit_variant_data(item, name, sd, gen)), + om.structs.push(self.visit_variant_data(item, ident.name, sd, gen)), hir::ItemKind::Union(ref sd, ref gen) => - om.unions.push(self.visit_union_data(item, name, sd, gen)), + om.unions.push(self.visit_union_data(item, ident.name, sd, gen)), hir::ItemKind::Fn(ref fd, header, ref gen, body) => - self.visit_fn(om, item, name, &**fd, header, gen, body), + self.visit_fn(om, item, ident.name, &**fd, header, gen, body), hir::ItemKind::Ty(ref ty, ref gen) => { let t = Typedef { ty: ty.clone(), gen: gen.clone(), - name, + name: ident.name, id: item.id, attrs: item.attrs.clone(), whence: item.span, @@ -487,7 +487,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { hir::ItemKind::Existential(ref exist_ty) => { let t = Existential { exist_ty: exist_ty.clone(), - name, + name: ident.name, id: item.id, attrs: item.attrs.clone(), whence: item.span, @@ -503,7 +503,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { mutability: mut_.clone(), expr: exp.clone(), id: item.id, - name, + name: ident.name, attrs: item.attrs.clone(), whence: item.span, vis: item.vis.clone(), @@ -517,7 +517,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { type_: ty.clone(), expr: exp.clone(), id: item.id, - name, + name: ident.name, attrs: item.attrs.clone(), whence: item.span, vis: item.vis.clone(), @@ -533,7 +533,7 @@ impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { let t = Trait { is_auto, unsafety, - name, + name: ident.name, items, generics: gen.clone(), bounds: b.iter().cloned().collect(), diff --git a/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs new file mode 100644 index 0000000000000..efef4ab00aed2 --- /dev/null +++ b/src/test/compile-fail-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -0,0 +1,51 @@ +// Copyright 2014 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// force-host + +#![feature(plugin_registrar)] +#![feature(box_syntax, rustc_private)] + +// Load rustc as a plugin to get macros. +#[macro_use] +extern crate rustc; +extern crate rustc_plugin; + +use rustc::hir; +use rustc::lint::{LateContext, LintContext, LintPass, LateLintPass, LateLintPassObject, LintArray}; +use rustc_plugin::Registry; + +declare_lint!(TEST_LINT, Warn, "Warn about items named 'lintme'"); + +declare_lint!(PLEASE_LINT, Warn, "Warn about items named 'pleaselintme'"); + +struct Pass; + +impl LintPass for Pass { + fn get_lints(&self) -> LintArray { + lint_array!(TEST_LINT, PLEASE_LINT) + } +} + +impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { + fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { + match &*it.ident.as_str() { + "lintme" => cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"), + "pleaselintme" => cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'"), + _ => {} + } + } +} + +#[plugin_registrar] +pub fn plugin_registrar(reg: &mut Registry) { + reg.register_late_lint_pass(box Pass); + reg.register_lint_group("lint_me", None, vec![TEST_LINT, PLEASE_LINT]); +} diff --git a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs index 91d03d98a10b9..bca1d7a72b4ab 100644 --- a/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs +++ b/src/test/ui-fulldeps/auxiliary/lint_group_plugin_test.rs @@ -3,7 +3,7 @@ #![feature(plugin_registrar)] #![feature(box_syntax, rustc_private)] -// Load rustc as a plugin to get macros +// Load rustc as a plugin to get macros. #[macro_use] extern crate rustc; extern crate rustc_plugin; @@ -26,7 +26,7 @@ impl LintPass for Pass { impl<'a, 'tcx> LateLintPass<'a, 'tcx> for Pass { fn check_item(&mut self, cx: &LateContext, it: &hir::Item) { - match &*it.name.as_str() { + match &*it.ident.as_str() { "lintme" => cx.span_lint(TEST_LINT, it.span, "item is named 'lintme'"), "pleaselintme" => cx.span_lint(PLEASE_LINT, it.span, "item is named 'pleaselintme'"), _ => {} diff --git a/src/test/ui-fulldeps/lint-group-plugin.rs b/src/test/ui-fulldeps/lint-group-plugin.rs index 00c5a56a482c1..7a650afe5f8fa 100644 --- a/src/test/ui-fulldeps/lint-group-plugin.rs +++ b/src/test/ui-fulldeps/lint-group-plugin.rs @@ -1,6 +1,7 @@ // run-pass // aux-build:lint_group_plugin_test.rs // ignore-stage1 + #![feature(plugin)] #![plugin(lint_group_plugin_test)] #![allow(dead_code)] diff --git a/src/test/ui-fulldeps/lint-group-plugin.stderr b/src/test/ui-fulldeps/lint-group-plugin.stderr index 15cffedcc5d3c..b566048c75ee6 100644 --- a/src/test/ui-fulldeps/lint-group-plugin.stderr +++ b/src/test/ui-fulldeps/lint-group-plugin.stderr @@ -1,5 +1,5 @@ warning: item is named 'lintme' - --> $DIR/lint-group-plugin.rs:8:1 + --> $DIR/lint-group-plugin.rs:9:1 | LL | fn lintme() { } //~ WARNING item is named 'lintme' | ^^^^^^^^^^^^^^^ @@ -7,7 +7,7 @@ LL | fn lintme() { } //~ WARNING item is named 'lintme' = note: #[warn(test_lint)] on by default warning: item is named 'pleaselintme' - --> $DIR/lint-group-plugin.rs:9:1 + --> $DIR/lint-group-plugin.rs:10:1 | LL | fn pleaselintme() { } //~ WARNING item is named 'pleaselintme' | ^^^^^^^^^^^^^^^^^^^^^ From c77fdbf2ebfa6a2f17017c38eebf18b4a802336a Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 3 Dec 2018 21:50:49 +0000 Subject: [PATCH 02/22] Implemented variants on type aliases in both ctor and pattern position. --- src/librustc_mir/hair/cx/expr.rs | 5 +- src/librustc_typeck/astconv.rs | 24 +++++- src/librustc_typeck/check/method/mod.rs | 35 ++++++-- src/librustc_typeck/check/mod.rs | 106 +++++++++++++++++++----- src/librustc_typeck/lib.rs | 26 ++++++ src/libsyntax/feature_gate.rs | 5 +- 6 files changed, 166 insertions(+), 35 deletions(-) diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 46d666cd81de2..2b790e3e1d34b 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -481,10 +481,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } } AdtKind::Enum => { - let def = match *qpath { - hir::QPath::Resolved(_, ref path) => path.def, - hir::QPath::TypeRelative(..) => Def::Err, - }; + let def = cx.tables().qpath_def(qpath, expr.hir_id); match def { Def::Variant(variant_id) => { assert!(base.is_none()); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f33060dde4f15..18c19352a603b 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -31,6 +31,8 @@ use std::collections::BTreeSet; use std::iter; use std::slice; +use super::{allow_type_alias_enum_variants}; + pub trait AstConv<'gcx, 'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>; @@ -1275,6 +1277,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { ref_id: ast::NodeId, span: Span, ty: Ty<'tcx>, + ty_hir: &hir::Ty, ty_path_def: Def, item_segment: &hir::PathSegment) -> (Ty<'tcx>, Def) @@ -1286,6 +1289,21 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { self.prohibit_generics(slice::from_ref(item_segment)); + // Check if we have an enum variant here. + if let ty::Adt(adt_def, _) = ty.sty { + if adt_def.is_enum() { + if allow_type_alias_enum_variants(tcx, ty_hir, span) { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + let def = Def::Variant(variant_def.did); + return (ty, def); + } + } + } + } + // Find the type of the associated item, and the trait where the associated // item is declared. let bound = match (&ty.sty, ty_path_def) { @@ -1342,7 +1360,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { return (tcx.types.err, Def::Err); } _ => { - // Don't print TyErr to the user. + // Don't print `TyErr` to the user. if !ty.references_error() { self.report_ambiguous_associated_type(span, &ty.to_string(), @@ -1505,10 +1523,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } Def::SelfTy(_, Some(def_id)) => { // `Self` in impl (we know the concrete type) - assert_eq!(opt_self_ty, None); self.prohibit_generics(&path.segments); - tcx.at(span).type_of(def_id) } Def::SelfTy(Some(_), None) => { @@ -1602,7 +1618,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else { Def::Err }; - self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0 + self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, qself, def, segment).0 } hir::TyKind::Array(ref ty, ref length) => { let length_def_id = tcx.hir().local_def_id(length.id); diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 2bc1dfaf04e37..f594690f77f02 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -1,4 +1,4 @@ -//! Method lookup: the secret sauce of Rust. See the [rustc guide] chapter. +//! Method lookup: the secret sauce of Rust. See the [rustc guide] for more information. //! //! [rustc guide]: https://rust-lang.github.io/rustc-guide/method-lookup.html @@ -25,6 +25,7 @@ use rustc::infer::{self, InferOk}; use syntax::ast; use syntax_pos::Span; +use crate::{allow_type_alias_enum_variants}; use self::probe::{IsSuggestion, ProbeScope}; pub fn provide(providers: &mut ty::query::Providers) { @@ -360,21 +361,45 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span, method_name: ast::Ident, self_ty: Ty<'tcx>, + self_ty_hir: &hir::Ty, expr_id: ast::NodeId) -> Result> { + debug!("resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}", + method_name, + self_ty, + expr_id + ); + + let tcx = self.tcx; + + // Check if we have an enum variant here. + if let ty::Adt(adt_def, _) = self_ty.sty { + if adt_def.is_enum() { + if allow_type_alias_enum_variants(tcx, self_ty_hir, span) { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(method_name, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); + return Ok(def); + } + } + } + } + let mode = probe::Mode::Path; let pick = self.probe_for_name(span, mode, method_name, IsSuggestion(false), self_ty, expr_id, ProbeScope::TraitsInScope)?; if let Some(import_id) = pick.import_id { - let import_def_id = self.tcx.hir().local_def_id(import_id); - debug!("used_trait_import: {:?}", import_def_id); + let import_def_id = tcx.hir().local_def_id(import_id); + debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id); Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) - .unwrap().insert(import_def_id); + .unwrap().insert(import_def_id); } let def = pick.item.def(); - self.tcx.check_stability(def.def_id(), Some(expr_id), span); + tcx.check_stability(def.def_id(), Some(expr_id), span); Ok(def) } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 414cc363f97a1..9914ae7ed8930 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -101,14 +101,14 @@ use rustc::infer::opaque_types::OpaqueTypeDecl; use rustc::infer::type_variable::{TypeVariableOrigin}; use rustc::middle::region; use rustc::mir::interpret::{ConstValue, GlobalId}; -use rustc::ty::subst::{CanonicalUserSubsts, UnpackedKind, Subst, Substs, - UserSelfTy, UserSubsts}; use rustc::traits::{self, ObligationCause, ObligationCauseCode, TraitEngine}; use rustc::ty::{self, AdtKind, Ty, TyCtxt, GenericParamDefKind, RegionKind, Visibility, ToPolyTraitRef, ToPredicate}; use rustc::ty::adjustment::{Adjust, Adjustment, AllowTwoPhase, AutoBorrow, AutoBorrowMutability}; use rustc::ty::fold::TypeFoldable; use rustc::ty::query::Providers; +use rustc::ty::subst::{CanonicalUserSubsts, UnpackedKind, Subst, Substs, + UserSelfTy, UserSubsts}; use rustc::ty::util::{Representability, IntTypeExt, Discr}; use rustc::ty::layout::VariantIdx; use syntax_pos::{self, BytePos, Span, MultiSpan}; @@ -4539,7 +4539,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Def::Err }; let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span, - ty, def, segment); + ty, qself, def, segment); // Write back the new resolution. let hir_id = self.tcx.hir().node_to_hir_id(node_id); @@ -4558,14 +4558,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span) -> (Def, Option>, &'b [hir::PathSegment]) { - let (ty, item_segment) = match *qpath { + let (ty, ty_hir, item_segment) = match *qpath { hir::QPath::Resolved(ref opt_qself, ref path) => { return (path.def, opt_qself.as_ref().map(|qself| self.to_ty(qself)), &path.segments[..]); } hir::QPath::TypeRelative(ref qself, ref segment) => { - (self.to_ty(qself), segment) + (self.to_ty(qself), qself, segment) } }; let hir_id = self.tcx.hir().node_to_hir_id(node_id); @@ -4575,7 +4575,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return (*cached_def, Some(ty), slice::from_ref(&**item_segment)) } let item_name = item_segment.ident; - let def = match self.resolve_ufcs(span, item_name, ty, node_id) { + let def = match self.resolve_ufcs(span, item_name, ty, ty_hir, node_id) { Ok(def) => def, Err(error) => { let def = match error { @@ -5042,6 +5042,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn def_ids_for_path_segments(&self, segments: &[hir::PathSegment], + self_ty: Option>, def: Def) -> Vec { // We need to extract the type parameters supplied by the user in @@ -5053,15 +5054,20 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // // There are basically four cases to consider: // - // 1. Reference to a constructor of enum variant or struct: + // 1. Reference to a constructor of a struct: // // struct Foo(...) + // + // In this case, the parameters are declared in the type space. + // + // 2. Reference to a constructor of an enum variant: + // // enum E { Foo(...) } // - // In these cases, the parameters are declared in the type - // space. + // In this case, the parameters are defined in the type space, + // but may be specified either on the type or the variant. // - // 2. Reference to a fn item or a free constant: + // 3. Reference to a fn item or a free constant: // // fn foo() { } // @@ -5070,7 +5076,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // type parameters. However, in this case, those parameters are // declared on a value, and hence are in the `FnSpace`. // - // 3. Reference to a method or an associated constant: + // 4. Reference to a method or an associated constant: // // impl SomeStruct { // fn foo(...) @@ -5082,7 +5088,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // `SomeStruct::`, contains parameters in TypeSpace, and the // final segment, `foo::` contains parameters in fn space. // - // 4. Reference to a local variable + // 5. Reference to a local variable // // Local variables can't have any type parameters. // @@ -5094,9 +5100,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut path_segs = vec![]; match def { - // Case 1. Reference to a struct/variant constructor. + // Case 1. Reference to a struct constructor. Def::StructCtor(def_id, ..) | - Def::VariantCtor(def_id, ..) | Def::SelfCtor(.., def_id) => { // Everything but the final segment should have no // parameters at all. @@ -5107,14 +5112,49 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { path_segs.push(PathSeg(generics_def_id, last)); } - // Case 2. Reference to a top-level value. + // Case 2. Reference to a variant constructor. + Def::VariantCtor(def_id, ..) => { + if tcx.features().type_alias_enum_variants { + let adt_def = self_ty.and_then(|t| t.ty_adt_def()); + let (generics_def_id, index) = if let Some(adt_def) = adt_def { + debug_assert!(adt_def.is_enum()); + (adt_def.did, last) + } else if last >= 1 && segments[last - 1].args.is_some() { + // Everything but the penultimate segment should have no + // parameters at all. + let enum_def_id = self.tcx.parent_def_id(def_id).unwrap(); + (enum_def_id, last - 1) + } else { + // FIXME: lint here suggesting `Enum::<...>::Variant` form + // instead of `Enum::Variant::<...>` form. + + // Everything but the final segment should have no + // parameters at all. + let generics = self.tcx.generics_of(def_id); + // Variant and struct constructors use the + // generics of their parent type definition. + (generics.parent.unwrap_or(def_id), last) + }; + path_segs.push(PathSeg(generics_def_id, index)); + } else { + // Everything but the final segment should have no + // parameters at all. + let generics = self.tcx.generics_of(def_id); + // Variant and struct constructors use the + // generics of their parent type definition. + let generics_def_id = generics.parent.unwrap_or(def_id); + path_segs.push(PathSeg(generics_def_id, last)); + } + } + + // Case 3. Reference to a top-level value. Def::Fn(def_id) | Def::Const(def_id) | Def::Static(def_id, _) => { path_segs.push(PathSeg(def_id, last)); } - // Case 3. Reference to a method or associated const. + // Case 4. Reference to a method or associated const. Def::Method(def_id) | Def::AssociatedConst(def_id) => { if segments.len() >= 2 { @@ -5124,7 +5164,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { path_segs.push(PathSeg(def_id, last)); } - // Case 4. Local variable, no generics. + // Case 5. Local variable, no generics. Def::Local(..) | Def::Upvar(..) => {} _ => bug!("unexpected definition: {:?}", def), @@ -5152,7 +5192,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { node_id, ); - let path_segs = self.def_ids_for_path_segments(segments, def); + let path_segs = self.def_ids_for_path_segments(segments, self_ty, def); let mut user_self_ty = None; match def { @@ -5187,10 +5227,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // provided (if any) into their appropriate spaces. We'll also report // errors if type parameters are provided in an inappropriate place. - let generic_segs = path_segs.iter().map(|PathSeg(_, index)| index) - .collect::>(); + let is_alias_variant_ctor = if tcx.features().type_alias_enum_variants { + match def { + Def::VariantCtor(_, _) if self_ty.is_some() => true, + _ => false, + }; + } else { + false + }; + + let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect(); AstConv::prohibit_generics(self, segments.iter().enumerate().filter_map(|(index, seg)| { - if !generic_segs.contains(&index) { + if !generic_segs.contains(&index) || is_alias_variant_ctor { Some(seg) } else { None @@ -5274,6 +5322,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } + Def::VariantCtor(_, _) if self_ty.is_some() => { + let def_id = def.def_id(); + + let ty = self.tcx.type_of(def_id); + if tcx.features().type_alias_enum_variants { + if let Some(self_ty) = self_ty { + match ty.ty_adt_def() { + Some(adt_def) if adt_def.is_enum() => { + return (self_ty, def); + } + _ => {} + } + } + } + (def_id, ty) + } _ => { let def_id = def.def_id(); diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index cba07ab3602c5..d63e5a3fe93a4 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -105,12 +105,14 @@ mod outlives; mod variance; use hir::Node; +use hir::def::Def; use rustc_target::spec::abi::Abi; use rustc::hir; use rustc::infer::InferOk; use rustc::lint; use rustc::middle; use rustc::session; +use rustc::session::config::nightly_options; use rustc::traits::{ObligationCause, ObligationCauseCode, TraitEngine, TraitEngineExt}; use rustc::ty::subst::Substs; use rustc::ty::{self, Ty, TyCtxt}; @@ -129,6 +131,30 @@ pub struct TypeAndSubsts<'tcx> { ty: Ty<'tcx>, } +fn allow_type_alias_enum_variants<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + ty_hir: &hir::Ty, + span: Span) -> bool { + let allow_feature = tcx.features().type_alias_enum_variants; + if !allow_feature { + // Only print error if we know the type is an alias. + if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ty_hir.node { + if let Def::TyAlias(_) = path.def { + let mut err = tcx.sess.struct_span_err( + span, + "type alias enum variants are not yet allowed" + ); + if nightly_options::is_nightly_build() { + help!(&mut err, + "add `#![feature(type_alias_enum_variants)]` to the \ + crate attributes to enable"); + } + err.emit(); + } + } + } + allow_feature +} + fn require_c_abi_if_variadic(tcx: TyCtxt, decl: &hir::FnDecl, abi: Abi, diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 62269a8f163b4..6a3b2156f3ae7 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -471,11 +471,14 @@ declare_features! ( // Allows `const _: TYPE = VALUE`. (active, underscore_const_names, "1.31.0", Some(54912), None), - // `reason = ` in lint attributes and `expect` lint attribute + // Adds `reason` and `expect` lint attributes. (active, lint_reasons, "1.31.0", Some(54503), None), // `extern crate self as foo;` puts local crate root into extern prelude under name `foo`. (active, extern_crate_self, "1.31.0", Some(56409), None), + + // Allows paths to enum variants on type aliases. + (active, type_alias_enum_variants, "1.31.0", Some(49683), None), ); declare_features! ( From ecacad07708a7ef756b45eae828d0c3b1e209c2c Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 3 Dec 2018 00:56:08 +0000 Subject: [PATCH 03/22] Added tests for feature. --- src/test/run-pass/type-alias-enum-variants.rs | 30 ++++++++ .../feature-gate-type_alias_enum_variants.rs | 25 +++++++ ...ature-gate-type_alias_enum_variants.stderr | 72 +++++++++++++++++++ src/test/ui/type-alias-enum-variants.rs | 10 +++ src/test/ui/type-alias-enum-variants.stderr | 9 +++ 5 files changed, 146 insertions(+) create mode 100644 src/test/run-pass/type-alias-enum-variants.rs create mode 100644 src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs create mode 100644 src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr create mode 100644 src/test/ui/type-alias-enum-variants.rs create mode 100644 src/test/ui/type-alias-enum-variants.stderr diff --git a/src/test/run-pass/type-alias-enum-variants.rs b/src/test/run-pass/type-alias-enum-variants.rs new file mode 100644 index 0000000000000..0cf413babcbf6 --- /dev/null +++ b/src/test/run-pass/type-alias-enum-variants.rs @@ -0,0 +1,30 @@ +#![feature(type_alias_enum_variants)] + +#[derive(Debug, PartialEq, Eq)] +enum Foo { + Bar(i32), + Baz { i: i32 }, +} + +type FooAlias = Foo; +type OptionAlias = Option; + +impl Foo { + fn foo() -> Self { + Self::Bar(3) + } +} + +fn main() { + let t = FooAlias::Bar(1); + assert_eq!(t, Foo::Bar(1)); + let t = FooAlias::Baz { i: 2 }; + assert_eq!(t, Foo::Baz { i: 2 }); + match t { + FooAlias::Bar(_i) => {} + FooAlias::Baz { i } => { assert_eq!(i, 2); } + } + assert_eq!(Foo::foo(), Foo::Bar(3)); + + assert_eq!(OptionAlias::Some(4), Option::Some(4)); +} diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs new file mode 100644 index 0000000000000..39472af43fdb2 --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs @@ -0,0 +1,25 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +enum Foo { + Bar(i32), + Baz { i: i32 }, +} + +type Alias = Foo; + +fn main() { + let t = Alias::Bar(0); + let t = Alias::Baz { i: 0 }; + match t { + Alias::Bar(_i) => {} + Alias::Baz { i: _i } => {} + } +} diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr new file mode 100644 index 0000000000000..7dce09e483f9d --- /dev/null +++ b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr @@ -0,0 +1,72 @@ +error: type alias enum variants are not yet allowed + --> $DIR/feature-gate-type_alias_enum_variants.rs:19:13 + | +LL | let t = Alias::Bar(0); + | ^^^^^^^^^^ + | + = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable + +error[E0599]: no variant named `Bar` found for type `Foo` in the current scope + --> $DIR/feature-gate-type_alias_enum_variants.rs:19:20 + | +LL | enum Foo { + | -------- variant `Bar` not found here +... +LL | let t = Alias::Bar(0); + | -------^^^ + | | + | variant not found in `Foo` + | + = help: did you mean `Bar`? + +error: type alias enum variants are not yet allowed + --> $DIR/feature-gate-type_alias_enum_variants.rs:20:13 + | +LL | let t = Alias::Baz { i: 0 }; + | ^^^^^^^^^^ + | + = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable + +error[E0223]: ambiguous associated type + --> $DIR/feature-gate-type_alias_enum_variants.rs:20:13 + | +LL | let t = Alias::Baz { i: 0 }; + | ^^^^^^^^^^ help: use fully-qualified syntax: `::Baz` + +error: type alias enum variants are not yet allowed + --> $DIR/feature-gate-type_alias_enum_variants.rs:22:9 + | +LL | Alias::Bar(_i) => {} + | ^^^^^^^^^^^^^^ + | + = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable + +error[E0599]: no variant named `Bar` found for type `Foo` in the current scope + --> $DIR/feature-gate-type_alias_enum_variants.rs:22:16 + | +LL | enum Foo { + | -------- variant `Bar` not found here +... +LL | Alias::Bar(_i) => {} + | -------^^^---- variant not found in `Foo` + | + = help: did you mean `Bar`? + +error: type alias enum variants are not yet allowed + --> $DIR/feature-gate-type_alias_enum_variants.rs:23:9 + | +LL | Alias::Baz { i: _i } => {} + | ^^^^^^^^^^ + | + = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable + +error[E0223]: ambiguous associated type + --> $DIR/feature-gate-type_alias_enum_variants.rs:23:9 + | +LL | Alias::Baz { i: _i } => {} + | ^^^^^^^^^^ help: use fully-qualified syntax: `::Baz` + +error: aborting due to 8 previous errors + +Some errors occurred: E0223, E0599. +For more information about an error, try `rustc --explain E0223`. diff --git a/src/test/ui/type-alias-enum-variants.rs b/src/test/ui/type-alias-enum-variants.rs new file mode 100644 index 0000000000000..8e5aaae0a9323 --- /dev/null +++ b/src/test/ui/type-alias-enum-variants.rs @@ -0,0 +1,10 @@ +#![feature(type_alias_enum_variants)] + +type Alias = Option; + +fn main() { + let _ = Option::::None; // OK + let _ = Option::None::; // OK (Lint in future!) + let _ = Alias::::None; // OK + let _ = Alias::None::; // Error +} diff --git a/src/test/ui/type-alias-enum-variants.stderr b/src/test/ui/type-alias-enum-variants.stderr new file mode 100644 index 0000000000000..e7003217c8d7c --- /dev/null +++ b/src/test/ui/type-alias-enum-variants.stderr @@ -0,0 +1,9 @@ +error[E0109]: type parameters are not allowed on this type + --> $DIR/type-alias-enum-variants.rs:9:27 + | +LL | let _ = Alias::None::; // Error + | ^^ type parameter not allowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0109`. From 767ffced9106c76647abf6b024bd05ba02d702b4 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 3 Dec 2018 00:56:47 +0000 Subject: [PATCH 04/22] Made suggestion diagnostics more consistent for enum variant names, relative to method names. --- src/librustc_typeck/astconv.rs | 12 ++-- src/librustc_typeck/check/method/mod.rs | 14 ++--- src/librustc_typeck/check/method/suggest.rs | 70 ++++++++++++--------- src/librustc_typeck/check/mod.rs | 53 +++++++++------- src/librustc_typeck/lib.rs | 4 +- 5 files changed, 84 insertions(+), 69 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 18c19352a603b..67f330536b85e 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1277,7 +1277,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { ref_id: ast::NodeId, span: Span, ty: Ty<'tcx>, - ty_hir: &hir::Ty, + qself: &hir::Ty, ty_path_def: Def, item_segment: &hir::PathSegment) -> (Ty<'tcx>, Def) @@ -1292,11 +1292,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // Check if we have an enum variant here. if let ty::Adt(adt_def, _) = ty.sty { if adt_def.is_enum() { - if allow_type_alias_enum_variants(tcx, ty_hir, span) { - let variant_def = adt_def.variants.iter().find(|vd| { - tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) - }); - if let Some(variant_def) = variant_def { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + if allow_type_alias_enum_variants(tcx, qself, span) { let def = Def::Variant(variant_def.did); return (ty, def); } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index f594690f77f02..4c96d476caa22 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -8,7 +8,7 @@ mod suggest; pub use self::MethodError::*; pub use self::CandidateSource::*; -pub use self::suggest::TraitInfo; +pub use self::suggest::{SelfSource, TraitInfo}; use check::FnCtxt; use namespace::Namespace; @@ -361,7 +361,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span, method_name: ast::Ident, self_ty: Ty<'tcx>, - self_ty_hir: &hir::Ty, + qself: &hir::Ty, expr_id: ast::NodeId) -> Result> { debug!("resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}", @@ -375,11 +375,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Check if we have an enum variant here. if let ty::Adt(adt_def, _) = self_ty.sty { if adt_def.is_enum() { - if allow_type_alias_enum_variants(tcx, self_ty_hir, span) { - let variant_def = adt_def.variants.iter().find(|vd| { - tcx.hygienic_eq(method_name, vd.ident, adt_def.did) - }); - if let Some(variant_def) = variant_def { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(method_name, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + if allow_type_alias_enum_variants(tcx, qself, span) { let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); return Ok(def); } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 65a58d345ccfa..b368250b32d97 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -6,7 +6,7 @@ use errors::{Applicability, DiagnosticBuilder}; use middle::lang_items::FnOnceTraitLangItem; use namespace::Namespace; use rustc_data_structures::sync::Lrc; -use rustc::hir::{self, Node}; +use rustc::hir::{self, ExprKind, Node, QPath}; use rustc::hir::def::Def; use rustc::hir::def_id::{CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::hir::map as hir_map; @@ -60,13 +60,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - pub fn report_method_error(&self, - span: Span, - rcvr_ty: Ty<'tcx>, - item_name: ast::Ident, - rcvr_expr: Option<&hir::Expr>, - error: MethodError<'tcx>, - args: Option<&'gcx [hir::Expr]>) { + pub fn report_method_error<'b>(&self, + span: Span, + rcvr_ty: Ty<'tcx>, + item_name: ast::Ident, + source: SelfSource<'b>, + error: MethodError<'tcx>, + args: Option<&'gcx [hir::Expr]>) { // Avoid suggestions when we don't know what's going on. if rcvr_ty.references_error() { return; @@ -212,10 +212,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { .filter_map(|info| self.associated_item(info.def_id, item_name, Namespace::Value) ); - if let (true, false, Some(expr), Some(_)) = (actual.is_numeric(), - actual.has_concrete_skeleton(), - rcvr_expr, - candidates.next()) { + if let (true, false, SelfSource::MethodCall(expr), Some(_)) = + (actual.is_numeric(), + actual.has_concrete_skeleton(), + source, + candidates.next()) { let mut err = struct_span_err!( tcx.sess, span, @@ -231,7 +232,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { "f32" }; match expr.node { - hir::ExprKind::Lit(ref lit) => { + ExprKind::Lit(ref lit) => { // numeric literal let snippet = tcx.sess.source_map().span_to_snippet(lit.span) .unwrap_or_else(|_| "".to_owned()); @@ -247,9 +248,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Applicability::MaybeIncorrect, ); } - hir::ExprKind::Path(ref qpath) => { + ExprKind::Path(ref qpath) => { // local binding - if let &hir::QPath::Resolved(_, ref path) = &qpath { + if let &QPath::Resolved(_, ref path) = &qpath { if let hir::def::Def::Local(node_id) = path.def { let span = tcx.hir().span(node_id); let snippet = tcx.sess.source_map().span_to_snippet(span) @@ -294,7 +295,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } else { let mut err = struct_span_err!( tcx.sess, - span, + item_name.span, E0599, "no {} named `{}` found for type `{}` in the current scope", item_kind, @@ -302,7 +303,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty_str ); if let Some(suggestion) = suggestion { - err.note(&format!("did you mean `{}::{}`?", ty_str, suggestion)); + // enum variant + err.help(&format!("did you mean `{}`?", suggestion)); } err } @@ -326,7 +328,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // If the method name is the name of a field with a function or closure type, // give a helping note that it has to be called as `(x.f)(...)`. - if let Some(expr) = rcvr_expr { + if let SelfSource::MethodCall(expr) = source { for (ty, _) in self.autoderef(span, rcvr_ty) { if let ty::Adt(def, substs) = ty.sty { if !def.is_enum() { @@ -377,10 +379,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - if let Some(expr) = rcvr_expr { + if let SelfSource::MethodCall(expr) = source { if let Ok(expr_string) = tcx.sess.source_map().span_to_snippet(expr.span) { report_function!(expr.span, expr_string); - } else if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = + } else if let ExprKind::Path(QPath::Resolved(_, ref path)) = expr.node { if let Some(segment) = path.segments.last() { @@ -396,7 +398,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { err.span_label(span, "this is an associated function, not a method"); } if static_sources.len() == 1 { - if let Some(expr) = rcvr_expr { + if let SelfSource::MethodCall(expr) = source { err.span_suggestion_with_applicability(expr.span.to(span), "use associated function syntax instead", format!("{}::{}", @@ -433,7 +435,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span, rcvr_ty, item_name, - rcvr_expr, + source, out_of_scope_traits); } @@ -571,18 +573,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - fn suggest_traits_to_import(&self, - err: &mut DiagnosticBuilder, - span: Span, - rcvr_ty: Ty<'tcx>, - item_name: ast::Ident, - rcvr_expr: Option<&hir::Expr>, - valid_out_of_scope_traits: Vec) { + fn suggest_traits_to_import<'b>(&self, + err: &mut DiagnosticBuilder, + span: Span, + rcvr_ty: Ty<'tcx>, + item_name: ast::Ident, + source: SelfSource<'b>, + valid_out_of_scope_traits: Vec) { if self.suggest_valid_traits(err, valid_out_of_scope_traits) { return; } - let type_is_local = self.type_derefs_to_local(span, rcvr_ty, rcvr_expr); + let type_is_local = self.type_derefs_to_local(span, rcvr_ty, source); // There are no traits implemented, so lets suggest some traits to // implement, by finding ones that have the item name, and are @@ -663,7 +665,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // This occurs for UFCS desugaring of `T::method`, where there is no // receiver expression for the method call, and thus no autoderef. - if rcvr_expr.is_none() { + if let SelfSource::QPath(_) = source { return is_local(self.resolve_type_vars_with_obligations(rcvr_ty)); } @@ -671,6 +673,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } +#[derive(Copy, Clone)] +pub enum SelfSource<'a> { + QPath(&'a hir::Ty), + MethodCall(&'a hir::Expr /* rcvr */), +} + #[derive(Copy, Clone)] pub struct TraitInfo { pub def_id: DefId, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 9914ae7ed8930..37739eb655fb3 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -142,7 +142,7 @@ use self::autoderef::Autoderef; use self::callee::DeferredCallResolution; use self::coercion::{CoerceMany, DynamicCoerceMany}; pub use self::compare_method::{compare_impl_method, compare_const_impl}; -use self::method::MethodCallee; +use self::method::{MethodCallee, SelfSource}; use self::TupleArgumentsFlag::*; /// The type of a local binding, including the revealed type for anon types. @@ -3244,7 +3244,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.report_method_error(span, rcvr_t, segment.ident, - Some(rcvr), + SelfSource::MethodCall(rcvr), error, Some(args)); } @@ -4558,7 +4558,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span) -> (Def, Option>, &'b [hir::PathSegment]) { - let (ty, ty_hir, item_segment) = match *qpath { + let (ty, qself, item_segment) = match *qpath { hir::QPath::Resolved(ref opt_qself, ref path) => { return (path.def, opt_qself.as_ref().map(|qself| self.to_ty(qself)), @@ -4575,7 +4575,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return (*cached_def, Some(ty), slice::from_ref(&**item_segment)) } let item_name = item_segment.ident; - let def = match self.resolve_ufcs(span, item_name, ty, ty_hir, node_id) { + let def = match self.resolve_ufcs(span, item_name, ty, qself, node_id) { Ok(def) => def, Err(error) => { let def = match error { @@ -4583,7 +4583,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { _ => Def::Err, }; if item_name.name != keywords::Invalid.name() { - self.report_method_error(span, ty, item_name, None, error, None); + self.report_method_error(span, + ty, + item_name, + SelfSource::QPath(qself), + error, + None); } def } @@ -5114,7 +5119,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Case 2. Reference to a variant constructor. Def::VariantCtor(def_id, ..) => { - if tcx.features().type_alias_enum_variants { + if self.tcx.features().type_alias_enum_variants { let adt_def = self_ty.and_then(|t| t.ty_adt_def()); let (generics_def_id, index) = if let Some(adt_def) = adt_def { debug_assert!(adt_def.is_enum()); @@ -5192,16 +5197,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { node_id, ); + let tcx = self.tcx; + let path_segs = self.def_ids_for_path_segments(segments, self_ty, def); let mut user_self_ty = None; match def { Def::Method(def_id) | Def::AssociatedConst(def_id) => { - let container = self.tcx.associated_item(def_id).container; + let container = tcx.associated_item(def_id).container; match container { ty::TraitContainer(trait_did) => { - callee::check_legal_trait_for_method_call(self.tcx, span, trait_did) + callee::check_legal_trait_for_method_call(tcx, span, trait_did) } ty::ImplContainer(impl_def_id) => { if segments.len() == 1 { @@ -5231,7 +5238,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { match def { Def::VariantCtor(_, _) if self_ty.is_some() => true, _ => false, - }; + } } else { false }; @@ -5249,7 +5256,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Def::Local(nid) | Def::Upvar(nid, ..) => { let ty = self.local_ty(span, nid).decl_ty; let ty = self.normalize_associated_types_in(span, &ty); - self.write_ty(self.tcx.hir().node_to_hir_id(node_id), ty); + self.write_ty(tcx.hir().node_to_hir_id(node_id), ty); return (ty, def); } _ => {} @@ -5265,13 +5272,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut infer_args_for_err = FxHashSet::default(); for &PathSeg(def_id, index) in &path_segs { let seg = &segments[index]; - let generics = self.tcx.generics_of(def_id); + let generics = tcx.generics_of(def_id); // Argument-position `impl Trait` is treated as a normal generic // parameter internally, but we don't allow users to specify the // parameter's value explicitly, so we have to do some error- // checking here. let suppress_errors = AstConv::check_generic_arg_count_for_call( - self.tcx, + tcx, span, &generics, &seg, @@ -5284,7 +5291,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } let has_self = path_segs.last().map(|PathSeg(def_id, _)| { - self.tcx.generics_of(*def_id).has_self + tcx.generics_of(*def_id).has_self }).unwrap_or(false); let mut new_def = def; @@ -5297,10 +5304,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(adt_def) if adt_def.has_ctor() => { let variant = adt_def.non_enum_variant(); new_def = Def::StructCtor(variant.did, variant.ctor_kind); - (variant.did, self.tcx.type_of(variant.did)) + (variant.did, tcx.type_of(variant.did)) } _ => { - let mut err = self.tcx.sess.struct_span_err(span, + let mut err = tcx.sess.struct_span_err(span, "the `Self` constructor can only be used with tuple or unit structs"); if let Some(adt_def) = adt_def { match adt_def.adt_kind() { @@ -5318,14 +5325,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } err.emit(); - (impl_def_id, self.tcx.types.err) + (impl_def_id, tcx.types.err) } } } Def::VariantCtor(_, _) if self_ty.is_some() => { let def_id = def.def_id(); - let ty = self.tcx.type_of(def_id); + let ty = tcx.type_of(def_id); if tcx.features().type_alias_enum_variants { if let Some(self_ty) = self_ty { match ty.ty_adt_def() { @@ -5343,13 +5350,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // The things we are substituting into the type should not contain // escaping late-bound regions, and nor should the base type scheme. - let ty = self.tcx.type_of(def_id); + let ty = tcx.type_of(def_id); (def_id, ty) } }; let substs = AstConv::create_substs_for_generic_args( - self.tcx, + tcx, def_id, &[][..], has_self, @@ -5395,10 +5402,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // If we have a default, then we it doesn't matter that we're not // inferring the type arguments: we provide the default where any // is missing. - let default = self.tcx.type_of(param.def_id); + let default = tcx.type_of(param.def_id); self.normalize_ty( span, - default.subst_spanned(self.tcx, substs.unwrap(), Some(span)) + default.subst_spanned(tcx, substs.unwrap(), Some(span)) ).into() } else { // If no type arguments were provided, we have to infer them. @@ -5415,7 +5422,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { assert!(!ty.has_escaping_bound_vars()); // First, store the "user substs" for later. - let hir_id = self.tcx.hir().node_to_hir_id(node_id); + let hir_id = tcx.hir().node_to_hir_id(node_id); self.write_user_substs_from_substs(hir_id, substs, user_self_ty); // Add all the obligations that are required, substituting and @@ -5434,7 +5441,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // is inherent, there is no `Self` parameter, instead, the impl needs // type parameters, which we can infer by unifying the provided `Self` // with the substituted impl type. - let ty = self.tcx.type_of(impl_def_id); + let ty = tcx.type_of(impl_def_id); let impl_ty = self.instantiate_type_scheme(span, &substs, &ty); match self.at(&self.misc(span), self.param_env).sup(impl_ty, self_ty) { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index d63e5a3fe93a4..4950ea319271b 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -132,12 +132,12 @@ pub struct TypeAndSubsts<'tcx> { } fn allow_type_alias_enum_variants<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - ty_hir: &hir::Ty, + qself: &hir::Ty, span: Span) -> bool { let allow_feature = tcx.features().type_alias_enum_variants; if !allow_feature { // Only print error if we know the type is an alias. - if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = ty_hir.node { + if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = qself.node { if let Def::TyAlias(_) = path.def { let mut err = tcx.sess.struct_span_err( span, From b9326f75fb875d08422d763d28e6dcc638676705 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 6 Dec 2018 01:02:21 +0000 Subject: [PATCH 05/22] Fixed tests. --- src/librustc_typeck/lib.rs | 2 +- .../feature-gate-type_alias_enum_variants.rs | 8 ++++++++ ...ature-gate-type_alias_enum_variants.stderr | 20 +++++++++---------- src/test/ui/type-alias-enum-variants.rs | 1 + 4 files changed, 20 insertions(+), 11 deletions(-) diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 4950ea319271b..8c0913a56b514 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -141,7 +141,7 @@ fn allow_type_alias_enum_variants<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, if let Def::TyAlias(_) = path.def { let mut err = tcx.sess.struct_span_err( span, - "type alias enum variants are not yet allowed" + "enum variants on type aliases are experimental" ); if nightly_options::is_nightly_build() { help!(&mut err, diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs index 39472af43fdb2..2dcd0dcd24381 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs +++ b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs @@ -17,9 +17,17 @@ type Alias = Foo; fn main() { let t = Alias::Bar(0); + //~^ ERROR enum variants on type aliases are experimental + //~^^ ERROR no variant named `Bar` found for type `Foo` in the current scope let t = Alias::Baz { i: 0 }; + //~^ ERROR enum variants on type aliases are experimental + //~^^ ERROR ambiguous associated type match t { Alias::Bar(_i) => {} + //~^ ERROR enum variants on type aliases are experimental + //~^^ ERROR no variant named `Bar` found for type `Foo` in the current scope Alias::Baz { i: _i } => {} + //~^ ERROR enum variants on type aliases are experimental + //~^^ ERROR ambiguous associated type } } diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr index 7dce09e483f9d..7a49770d97a2f 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr +++ b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr @@ -1,4 +1,4 @@ -error: type alias enum variants are not yet allowed +error: enum variants on type aliases are experimental --> $DIR/feature-gate-type_alias_enum_variants.rs:19:13 | LL | let t = Alias::Bar(0); @@ -19,8 +19,8 @@ LL | let t = Alias::Bar(0); | = help: did you mean `Bar`? -error: type alias enum variants are not yet allowed - --> $DIR/feature-gate-type_alias_enum_variants.rs:20:13 +error: enum variants on type aliases are experimental + --> $DIR/feature-gate-type_alias_enum_variants.rs:22:13 | LL | let t = Alias::Baz { i: 0 }; | ^^^^^^^^^^ @@ -28,13 +28,13 @@ LL | let t = Alias::Baz { i: 0 }; = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable error[E0223]: ambiguous associated type - --> $DIR/feature-gate-type_alias_enum_variants.rs:20:13 + --> $DIR/feature-gate-type_alias_enum_variants.rs:22:13 | LL | let t = Alias::Baz { i: 0 }; | ^^^^^^^^^^ help: use fully-qualified syntax: `::Baz` -error: type alias enum variants are not yet allowed - --> $DIR/feature-gate-type_alias_enum_variants.rs:22:9 +error: enum variants on type aliases are experimental + --> $DIR/feature-gate-type_alias_enum_variants.rs:26:9 | LL | Alias::Bar(_i) => {} | ^^^^^^^^^^^^^^ @@ -42,7 +42,7 @@ LL | Alias::Bar(_i) => {} = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable error[E0599]: no variant named `Bar` found for type `Foo` in the current scope - --> $DIR/feature-gate-type_alias_enum_variants.rs:22:16 + --> $DIR/feature-gate-type_alias_enum_variants.rs:26:16 | LL | enum Foo { | -------- variant `Bar` not found here @@ -52,8 +52,8 @@ LL | Alias::Bar(_i) => {} | = help: did you mean `Bar`? -error: type alias enum variants are not yet allowed - --> $DIR/feature-gate-type_alias_enum_variants.rs:23:9 +error: enum variants on type aliases are experimental + --> $DIR/feature-gate-type_alias_enum_variants.rs:29:9 | LL | Alias::Baz { i: _i } => {} | ^^^^^^^^^^ @@ -61,7 +61,7 @@ LL | Alias::Baz { i: _i } => {} = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable error[E0223]: ambiguous associated type - --> $DIR/feature-gate-type_alias_enum_variants.rs:23:9 + --> $DIR/feature-gate-type_alias_enum_variants.rs:29:9 | LL | Alias::Baz { i: _i } => {} | ^^^^^^^^^^ help: use fully-qualified syntax: `::Baz` diff --git a/src/test/ui/type-alias-enum-variants.rs b/src/test/ui/type-alias-enum-variants.rs index 8e5aaae0a9323..73395e6a9798a 100644 --- a/src/test/ui/type-alias-enum-variants.rs +++ b/src/test/ui/type-alias-enum-variants.rs @@ -7,4 +7,5 @@ fn main() { let _ = Option::None::; // OK (Lint in future!) let _ = Alias::::None; // OK let _ = Alias::None::; // Error + //~^ type parameters are not allowed on this type } From 58a5756f4d805d0c2895454153920f1457f9ca2a Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Fri, 7 Dec 2018 18:15:36 +0000 Subject: [PATCH 06/22] Fixed more tests. --- .../associated-const-no-item.stderr | 6 +++-- src/test/ui/bogus-tag.rs | 6 ++--- src/test/ui/bogus-tag.stderr | 6 ++--- src/test/ui/did_you_mean/bad-assoc-pat.stderr | 24 ++++++++++++------- .../dont-suggest-private-trait-method.stderr | 6 +++-- .../ui/empty/empty-struct-braces-expr.stderr | 16 ++++++++----- src/test/ui/error-codes/E0599.stderr | 4 ++-- .../ui/invalid/invalid-path-in-const.stderr | 6 +++-- src/test/ui/issues/issue-22933-2.stderr | 6 +++-- src/test/ui/issues/issue-22933-3.stderr | 6 +++-- src/test/ui/issues/issue-23173.stderr | 24 ++++++++++++------- src/test/ui/issues/issue-23217.stderr | 8 ++++--- src/test/ui/issues/issue-28344.stderr | 12 ++++++---- src/test/ui/issues/issue-28586.stderr | 6 +++-- src/test/ui/issues/issue-28971.stderr | 6 ++--- src/test/ui/issues/issue-30123.stderr | 6 +++-- src/test/ui/issues/issue-38919.stderr | 6 +++-- src/test/ui/issues/issue-39559.stderr | 6 +++-- src/test/ui/issues/issue-3973.stderr | 6 +++-- src/test/ui/issues/issue-42880.stderr | 4 ++-- src/test/ui/issues/issue-7950.stderr | 6 +++-- src/test/ui/lexical-scopes.stderr | 6 +++-- .../no-double-error.stderr | 6 +++-- .../rust-2018/trait-import-suggestions.stderr | 6 +++-- src/test/ui/traits/trait-item-privacy.stderr | 24 ++++++++++++------- .../ui/ufcs/ufcs-partially-resolved.stderr | 12 ++++++---- .../ui/unspecified-self-in-trait-ref.stderr | 24 ++++++++++++------- 27 files changed, 164 insertions(+), 90 deletions(-) diff --git a/src/test/ui/associated-const/associated-const-no-item.stderr b/src/test/ui/associated-const/associated-const-no-item.stderr index cd60132efdd65..de172049872f5 100644 --- a/src/test/ui/associated-const/associated-const-no-item.stderr +++ b/src/test/ui/associated-const/associated-const-no-item.stderr @@ -1,8 +1,10 @@ error[E0599]: no associated item named `ID` found for type `i32` in the current scope - --> $DIR/associated-const-no-item.rs:5:16 + --> $DIR/associated-const-no-item.rs:5:23 | LL | const X: i32 = ::ID; - | ^^^^^^^^^ associated item not found in `i32` + | -------^^ + | | + | associated item not found in `i32` | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `ID`, perhaps you need to implement it: diff --git a/src/test/ui/bogus-tag.rs b/src/test/ui/bogus-tag.rs index ca8db9b502b5b..c594385eec2d6 100644 --- a/src/test/ui/bogus-tag.rs +++ b/src/test/ui/bogus-tag.rs @@ -3,8 +3,8 @@ enum Color { Rgb(isize, isize, isize), Rgba(isize, isize, isize, isize), } fn main() { let red: Color = Color::Rgb(255, 0, 0); match red { - Color::Rgb(r, g, b) => { println!("rgb"); } - Color::Hsl(h, s, l) => { println!("hsl"); } - //~^ ERROR no variant + Color::Rgb(r, g, b) => { println!("rgb"); } + Color::Hsl(h, s, l) => { println!("hsl"); } + //~^ ERROR no variant } } diff --git a/src/test/ui/bogus-tag.stderr b/src/test/ui/bogus-tag.stderr index 1225abd2c8a16..1cb5ee9b6305c 100644 --- a/src/test/ui/bogus-tag.stderr +++ b/src/test/ui/bogus-tag.stderr @@ -1,11 +1,11 @@ error[E0599]: no variant named `Hsl` found for type `Color` in the current scope - --> $DIR/bogus-tag.rs:7:7 + --> $DIR/bogus-tag.rs:7:9 | LL | enum Color { Rgb(isize, isize, isize), Rgba(isize, isize, isize, isize), } | ---------- variant `Hsl` not found here ... -LL | Color::Hsl(h, s, l) => { println!("hsl"); } - | ^^^^^^^^^^^^^^^^^^^ variant not found in `Color` +LL | Color::Hsl(h, s, l) => { println!("hsl"); } + | ^^^^^^^^^^^^^^^^^^^ variant not found in `Color` error: aborting due to previous error diff --git a/src/test/ui/did_you_mean/bad-assoc-pat.stderr b/src/test/ui/did_you_mean/bad-assoc-pat.stderr index 86beb0f33f64a..92fd9f26777f1 100644 --- a/src/test/ui/did_you_mean/bad-assoc-pat.stderr +++ b/src/test/ui/did_you_mean/bad-assoc-pat.stderr @@ -23,28 +23,36 @@ LL | &(u8,)::AssocItem => {} | ^^^^^^^^^^^^^^^^ help: try: `<(u8,)>::AssocItem` error[E0599]: no associated item named `AssocItem` found for type `[u8]` in the current scope - --> $DIR/bad-assoc-pat.rs:3:9 + --> $DIR/bad-assoc-pat.rs:3:15 | LL | [u8]::AssocItem => {} - | ^^^^^^^^^^^^^^^ associated item not found in `[u8]` + | ------^^^^^^^^^ + | | + | associated item not found in `[u8]` error[E0599]: no associated item named `AssocItem` found for type `(u8, u8)` in the current scope - --> $DIR/bad-assoc-pat.rs:6:9 + --> $DIR/bad-assoc-pat.rs:6:19 | LL | (u8, u8)::AssocItem => {} - | ^^^^^^^^^^^^^^^^^^^ associated item not found in `(u8, u8)` + | ----------^^^^^^^^^ + | | + | associated item not found in `(u8, u8)` error[E0599]: no associated item named `AssocItem` found for type `_` in the current scope - --> $DIR/bad-assoc-pat.rs:9:9 + --> $DIR/bad-assoc-pat.rs:9:12 | LL | _::AssocItem => {} - | ^^^^^^^^^^^^ associated item not found in `_` + | ---^^^^^^^^^ + | | + | associated item not found in `_` error[E0599]: no associated item named `AssocItem` found for type `(u8,)` in the current scope - --> $DIR/bad-assoc-pat.rs:14:10 + --> $DIR/bad-assoc-pat.rs:14:17 | LL | &(u8,)::AssocItem => {} - | ^^^^^^^^^^^^^^^^ associated item not found in `(u8,)` + | -------^^^^^^^^^ + | | + | associated item not found in `(u8,)` error: aborting due to 8 previous errors diff --git a/src/test/ui/dont-suggest-private-trait-method.stderr b/src/test/ui/dont-suggest-private-trait-method.stderr index 483192149b850..af4253779a4f5 100644 --- a/src/test/ui/dont-suggest-private-trait-method.stderr +++ b/src/test/ui/dont-suggest-private-trait-method.stderr @@ -1,11 +1,13 @@ error[E0599]: no function or associated item named `new` found for type `T` in the current scope - --> $DIR/dont-suggest-private-trait-method.rs:4:5 + --> $DIR/dont-suggest-private-trait-method.rs:4:8 | LL | struct T; | --------- function or associated item `new` not found for this ... LL | T::new(); - | ^^^^^^ function or associated item not found in `T` + | ---^^^ + | | + | function or associated item not found in `T` error: aborting due to previous error diff --git a/src/test/ui/empty/empty-struct-braces-expr.stderr b/src/test/ui/empty/empty-struct-braces-expr.stderr index be613121fe88e..d3e1cebd26fe1 100644 --- a/src/test/ui/empty/empty-struct-braces-expr.stderr +++ b/src/test/ui/empty/empty-struct-braces-expr.stderr @@ -47,20 +47,24 @@ LL | let xe1 = XEmpty1(); //~ ERROR expected function, found struct `XEmpty1 | did you mean `XEmpty1 { /* fields */ }`? error[E0599]: no variant named `Empty3` found for type `empty_struct::XE` in the current scope - --> $DIR/empty-struct-braces-expr.rs:22:15 + --> $DIR/empty-struct-braces-expr.rs:22:19 | LL | let xe3 = XE::Empty3; //~ ERROR no variant named `Empty3` found for type - | ^^^^^^^^^^ variant not found in `empty_struct::XE` + | ----^^^^^^ + | | + | variant not found in `empty_struct::XE` | - = note: did you mean `empty_struct::XE::XEmpty3`? + = help: did you mean `XEmpty3`? error[E0599]: no variant named `Empty3` found for type `empty_struct::XE` in the current scope - --> $DIR/empty-struct-braces-expr.rs:23:15 + --> $DIR/empty-struct-braces-expr.rs:23:19 | LL | let xe3 = XE::Empty3(); //~ ERROR no variant named `Empty3` found for type - | ^^^^^^^^^^ variant not found in `empty_struct::XE` + | ----^^^^^^ + | | + | variant not found in `empty_struct::XE` | - = note: did you mean `empty_struct::XE::XEmpty3`? + = help: did you mean `XEmpty3`? error: aborting due to 8 previous errors diff --git a/src/test/ui/error-codes/E0599.stderr b/src/test/ui/error-codes/E0599.stderr index 5a7cddbf38210..85110889e9a7b 100644 --- a/src/test/ui/error-codes/E0599.stderr +++ b/src/test/ui/error-codes/E0599.stderr @@ -1,11 +1,11 @@ error[E0599]: no associated item named `NotEvenReal` found for type `Foo` in the current scope - --> $DIR/E0599.rs:4:15 + --> $DIR/E0599.rs:4:20 | LL | struct Foo; | ----------- associated item `NotEvenReal` not found for this ... LL | || if let Foo::NotEvenReal() = Foo {}; //~ ERROR E0599 - | ^^^^^^^^^^^^^^^^^^ associated item not found in `Foo` + | -----^^^^^^^^^^^-- associated item not found in `Foo` error: aborting due to previous error diff --git a/src/test/ui/invalid/invalid-path-in-const.stderr b/src/test/ui/invalid/invalid-path-in-const.stderr index 6541c92c691c8..13176b8b8fb15 100644 --- a/src/test/ui/invalid/invalid-path-in-const.stderr +++ b/src/test/ui/invalid/invalid-path-in-const.stderr @@ -1,8 +1,10 @@ error[E0599]: no associated item named `DOESNOTEXIST` found for type `u32` in the current scope - --> $DIR/invalid-path-in-const.rs:2:18 + --> $DIR/invalid-path-in-const.rs:2:23 | LL | fn f(a: [u8; u32::DOESNOTEXIST]) {} - | ^^^^^^^^^^^^^^^^^ associated item not found in `u32` + | -----^^^^^^^^^^^^ + | | + | associated item not found in `u32` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-22933-2.stderr b/src/test/ui/issues/issue-22933-2.stderr index 58145a38026e4..97962adc2d286 100644 --- a/src/test/ui/issues/issue-22933-2.stderr +++ b/src/test/ui/issues/issue-22933-2.stderr @@ -1,11 +1,13 @@ error[E0599]: no variant named `PIE` found for type `Delicious` in the current scope - --> $DIR/issue-22933-2.rs:4:44 + --> $DIR/issue-22933-2.rs:4:55 | LL | enum Delicious { | -------------- variant `PIE` not found here ... LL | ApplePie = Delicious::Apple as isize | Delicious::PIE as isize, - | ^^^^^^^^^^^^^^ variant not found in `Delicious` + | -----------^^^ + | | + | variant not found in `Delicious` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-22933-3.stderr b/src/test/ui/issues/issue-22933-3.stderr index 2ca1bd7401a20..aa0052f97013e 100644 --- a/src/test/ui/issues/issue-22933-3.stderr +++ b/src/test/ui/issues/issue-22933-3.stderr @@ -1,8 +1,10 @@ error[E0599]: no associated item named `MIN` found for type `u8` in the current scope - --> $DIR/issue-22933-3.rs:1:18 + --> $DIR/issue-22933-3.rs:1:22 | LL | const FOO: [u32; u8::MIN as usize] = []; - | ^^^^^^^ associated item not found in `u8` + | ----^^^ + | | + | associated item not found in `u8` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-23173.stderr b/src/test/ui/issues/issue-23173.stderr index de4c8422b9ccb..98c4f867ad6a0 100644 --- a/src/test/ui/issues/issue-23173.stderr +++ b/src/test/ui/issues/issue-23173.stderr @@ -1,38 +1,46 @@ error[E0599]: no variant named `Homura` found for type `Token` in the current scope - --> $DIR/issue-23173.rs:9:16 + --> $DIR/issue-23173.rs:9:23 | LL | enum Token { LeftParen, RightParen, Plus, Minus, /* etc */ } | ---------- variant `Homura` not found here ... LL | use_token(&Token::Homura); - | ^^^^^^^^^^^^^ variant not found in `Token` + | -------^^^^^^ + | | + | variant not found in `Token` error[E0599]: no function or associated item named `method` found for type `Struct` in the current scope - --> $DIR/issue-23173.rs:11:5 + --> $DIR/issue-23173.rs:11:13 | LL | struct Struct { | ------------- function or associated item `method` not found for this ... LL | Struct::method(); - | ^^^^^^^^^^^^^^ function or associated item not found in `Struct` + | --------^^^^^^ + | | + | function or associated item not found in `Struct` error[E0599]: no function or associated item named `method` found for type `Struct` in the current scope - --> $DIR/issue-23173.rs:13:5 + --> $DIR/issue-23173.rs:13:13 | LL | struct Struct { | ------------- function or associated item `method` not found for this ... LL | Struct::method; - | ^^^^^^^^^^^^^^ function or associated item not found in `Struct` + | --------^^^^^^ + | | + | function or associated item not found in `Struct` error[E0599]: no associated item named `Assoc` found for type `Struct` in the current scope - --> $DIR/issue-23173.rs:15:5 + --> $DIR/issue-23173.rs:15:13 | LL | struct Struct { | ------------- associated item `Assoc` not found for this ... LL | Struct::Assoc; - | ^^^^^^^^^^^^^ associated item not found in `Struct` + | --------^^^^^ + | | + | associated item not found in `Struct` error: aborting due to 4 previous errors diff --git a/src/test/ui/issues/issue-23217.stderr b/src/test/ui/issues/issue-23217.stderr index a058caf81bbe8..208d0cc499a80 100644 --- a/src/test/ui/issues/issue-23217.stderr +++ b/src/test/ui/issues/issue-23217.stderr @@ -1,12 +1,14 @@ error[E0599]: no variant named `A` found for type `SomeEnum` in the current scope - --> $DIR/issue-23217.rs:2:9 + --> $DIR/issue-23217.rs:2:19 | LL | pub enum SomeEnum { | ----------------- variant `A` not found here LL | B = SomeEnum::A, - | ^^^^^^^^^^^ variant not found in `SomeEnum` + | ----------^ + | | + | variant not found in `SomeEnum` | - = note: did you mean `SomeEnum::B`? + = help: did you mean `B`? error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28344.stderr b/src/test/ui/issues/issue-28344.stderr index f7d8d2af86208..146ebad6ce175 100644 --- a/src/test/ui/issues/issue-28344.stderr +++ b/src/test/ui/issues/issue-28344.stderr @@ -5,10 +5,12 @@ LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); | ^^^^^^^^^^^^^ associated type `Output` must be specified error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope - --> $DIR/issue-28344.rs:4:17 + --> $DIR/issue-28344.rs:4:25 | LL | let x: u8 = BitXor::bitor(0 as u8, 0 as u8); - | ^^^^^^^^^^^^^ function or associated item not found in `dyn std::ops::BitXor<_>` + | --------^^^^^ + | | + | function or associated item not found in `dyn std::ops::BitXor<_>` | = help: did you mean `bitxor`? @@ -19,10 +21,12 @@ LL | let g = BitXor::bitor; | ^^^^^^^^^^^^^ associated type `Output` must be specified error[E0599]: no function or associated item named `bitor` found for type `dyn std::ops::BitXor<_>` in the current scope - --> $DIR/issue-28344.rs:8:13 + --> $DIR/issue-28344.rs:8:21 | LL | let g = BitXor::bitor; - | ^^^^^^^^^^^^^ function or associated item not found in `dyn std::ops::BitXor<_>` + | --------^^^^^ + | | + | function or associated item not found in `dyn std::ops::BitXor<_>` | = help: did you mean `bitxor`? diff --git a/src/test/ui/issues/issue-28586.stderr b/src/test/ui/issues/issue-28586.stderr index 52af2f54653f3..eccb474c15eb6 100644 --- a/src/test/ui/issues/issue-28586.stderr +++ b/src/test/ui/issues/issue-28586.stderr @@ -1,8 +1,10 @@ error[E0599]: no associated item named `BYTES` found for type `usize` in the current scope - --> $DIR/issue-28586.rs:4:19 + --> $DIR/issue-28586.rs:4:26 | LL | impl Foo for [u8; usize::BYTES] {} - | ^^^^^^^^^^^^ associated item not found in `usize` + | -------^^^^^ + | | + | associated item not found in `usize` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-28971.stderr b/src/test/ui/issues/issue-28971.stderr index f6362faab12b8..d5dbd5f64885c 100644 --- a/src/test/ui/issues/issue-28971.stderr +++ b/src/test/ui/issues/issue-28971.stderr @@ -1,13 +1,13 @@ error[E0599]: no variant named `Baz` found for type `Foo` in the current scope - --> $DIR/issue-28971.rs:9:13 + --> $DIR/issue-28971.rs:9:18 | LL | enum Foo { | -------- variant `Baz` not found here ... LL | Foo::Baz(..) => (), - | ^^^^^^^^^^^^ variant not found in `Foo` + | -----^^^---- variant not found in `Foo` | - = note: did you mean `Foo::Bar`? + = help: did you mean `Bar`? error: aborting due to previous error diff --git a/src/test/ui/issues/issue-30123.stderr b/src/test/ui/issues/issue-30123.stderr index 9729b13d57fe8..555bdb1236fe6 100644 --- a/src/test/ui/issues/issue-30123.stderr +++ b/src/test/ui/issues/issue-30123.stderr @@ -1,8 +1,10 @@ error[E0599]: no function or associated item named `new_undirected` found for type `issue_30123_aux::Graph` in the current scope - --> $DIR/issue-30123.rs:7:14 + --> $DIR/issue-30123.rs:7:33 | LL | let ug = Graph::::new_undirected(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `issue_30123_aux::Graph` + | -------------------^^^^^^^^^^^^^^ + | | + | function or associated item not found in `issue_30123_aux::Graph` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-38919.stderr b/src/test/ui/issues/issue-38919.stderr index 41da422c1b960..8c09436479564 100644 --- a/src/test/ui/issues/issue-38919.stderr +++ b/src/test/ui/issues/issue-38919.stderr @@ -1,8 +1,10 @@ error[E0599]: no associated item named `Item` found for type `T` in the current scope - --> $DIR/issue-38919.rs:2:5 + --> $DIR/issue-38919.rs:2:8 | LL | T::Item; //~ ERROR no associated item named `Item` found for type `T` in the current scope - | ^^^^^^^ associated item not found in `T` + | ---^^^^ + | | + | associated item not found in `T` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-39559.stderr b/src/test/ui/issues/issue-39559.stderr index 7653cadc6a777..e851e79faee06 100644 --- a/src/test/ui/issues/issue-39559.stderr +++ b/src/test/ui/issues/issue-39559.stderr @@ -1,8 +1,10 @@ error[E0599]: no function or associated item named `dim` found for type `D` in the current scope - --> $DIR/issue-39559.rs:14:18 + --> $DIR/issue-39559.rs:14:21 | LL | entries: [T; D::dim()], - | ^^^^^^ function or associated item not found in `D` + | ---^^^ + | | + | function or associated item not found in `D` | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `dim`, perhaps you need to implement it: diff --git a/src/test/ui/issues/issue-3973.stderr b/src/test/ui/issues/issue-3973.stderr index 0f9c15647492e..8e46d88018112 100644 --- a/src/test/ui/issues/issue-3973.stderr +++ b/src/test/ui/issues/issue-3973.stderr @@ -8,13 +8,15 @@ LL | | } | |_____^ not a member of trait `ToString_` error[E0599]: no function or associated item named `new` found for type `Point` in the current scope - --> $DIR/issue-3973.rs:22:13 + --> $DIR/issue-3973.rs:22:20 | LL | struct Point { | ------------ function or associated item `new` not found for this ... LL | let p = Point::new(0.0, 0.0); - | ^^^^^^^^^^ function or associated item not found in `Point` + | -------^^^ + | | + | function or associated item not found in `Point` error: aborting due to 2 previous errors diff --git a/src/test/ui/issues/issue-42880.stderr b/src/test/ui/issues/issue-42880.stderr index 7d8bae9cafc6f..36b9e8a1e8afa 100644 --- a/src/test/ui/issues/issue-42880.stderr +++ b/src/test/ui/issues/issue-42880.stderr @@ -1,8 +1,8 @@ error[E0599]: no associated item named `String` found for type `std::string::String` in the current scope - --> $DIR/issue-42880.rs:4:15 + --> $DIR/issue-42880.rs:4:22 | LL | let f = |&Value::String(_)| (); //~ ERROR no associated item named - | ^^^^^^^^^^^^^^^^ associated item not found in `std::string::String` + | -------^^^^^^--- associated item not found in `std::string::String` error: aborting due to previous error diff --git a/src/test/ui/issues/issue-7950.stderr b/src/test/ui/issues/issue-7950.stderr index 169ce5429f5af..e30f04753762e 100644 --- a/src/test/ui/issues/issue-7950.stderr +++ b/src/test/ui/issues/issue-7950.stderr @@ -1,11 +1,13 @@ error[E0599]: no function or associated item named `bar` found for type `Foo` in the current scope - --> $DIR/issue-7950.rs:6:5 + --> $DIR/issue-7950.rs:6:10 | LL | struct Foo; | ----------- function or associated item `bar` not found for this ... LL | Foo::bar(); - | ^^^^^^^^ function or associated item not found in `Foo` + | -----^^^ + | | + | function or associated item not found in `Foo` error: aborting due to previous error diff --git a/src/test/ui/lexical-scopes.stderr b/src/test/ui/lexical-scopes.stderr index 7ac629b5dea19..51313033a02dd 100644 --- a/src/test/ui/lexical-scopes.stderr +++ b/src/test/ui/lexical-scopes.stderr @@ -9,10 +9,12 @@ LL | use T; | error[E0599]: no function or associated item named `f` found for type `Foo` in the current scope - --> $DIR/lexical-scopes.rs:10:5 + --> $DIR/lexical-scopes.rs:10:10 | LL | Foo::f(); //~ ERROR no function or associated item named `f` - | ^^^^^^ function or associated item not found in `Foo` + | -----^ + | | + | function or associated item not found in `Foo` error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr index dee32024e4702..9d35e167075ae 100644 --- a/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr +++ b/src/test/ui/rfc-2005-default-binding-mode/no-double-error.stderr @@ -1,8 +1,10 @@ error[E0599]: no associated item named `XXX` found for type `u32` in the current scope - --> $DIR/no-double-error.rs:8:9 + --> $DIR/no-double-error.rs:8:14 | LL | u32::XXX => { } //~ ERROR no associated item named - | ^^^^^^^^ associated item not found in `u32` + | -----^^^ + | | + | associated item not found in `u32` error: aborting due to previous error diff --git a/src/test/ui/rust-2018/trait-import-suggestions.stderr b/src/test/ui/rust-2018/trait-import-suggestions.stderr index e97cb3187846f..e4c17680c90a5 100644 --- a/src/test/ui/rust-2018/trait-import-suggestions.stderr +++ b/src/test/ui/rust-2018/trait-import-suggestions.stderr @@ -27,10 +27,12 @@ LL | x.baz(); //~ ERROR no method named `baz` | ^^^ error[E0599]: no function or associated item named `from_str` found for type `u32` in the current scope - --> $DIR/trait-import-suggestions.rs:30:13 + --> $DIR/trait-import-suggestions.rs:30:18 | LL | let y = u32::from_str("33"); //~ ERROR no function or associated item named `from_str` - | ^^^^^^^^^^^^^ function or associated item not found in `u32` + | -----^^^^^^^^ + | | + | function or associated item not found in `u32` | = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope, perhaps add a `use` for it: diff --git a/src/test/ui/traits/trait-item-privacy.stderr b/src/test/ui/traits/trait-item-privacy.stderr index 5913f7b4b18a0..c65a9a3ed945c 100644 --- a/src/test/ui/traits/trait-item-privacy.stderr +++ b/src/test/ui/traits/trait-item-privacy.stderr @@ -33,26 +33,30 @@ LL | c.a(); //~ ERROR method `a` is private | ^ error[E0599]: no function or associated item named `a` found for type `S` in the current scope - --> $DIR/trait-item-privacy.rs:78:5 + --> $DIR/trait-item-privacy.rs:78:8 | LL | struct S; | --------- function or associated item `a` not found for this ... LL | S::a(&S); - | ^^^^ function or associated item not found in `S` + | ---^ + | | + | function or associated item not found in `S` | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `a`, perhaps you need to implement it: candidate #1: `method::A` error[E0599]: no function or associated item named `b` found for type `S` in the current scope - --> $DIR/trait-item-privacy.rs:80:5 + --> $DIR/trait-item-privacy.rs:80:8 | LL | struct S; | --------- function or associated item `b` not found for this ... LL | S::b(&S); - | ^^^^ function or associated item not found in `S` + | ---^ + | | + | function or associated item not found in `S` | = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope, perhaps add a `use` for it: @@ -67,26 +71,30 @@ LL | C::a(&S); //~ ERROR method `a` is private | ^^^^ error[E0599]: no associated item named `A` found for type `S` in the current scope - --> $DIR/trait-item-privacy.rs:97:5 + --> $DIR/trait-item-privacy.rs:97:8 | LL | struct S; | --------- associated item `A` not found for this ... LL | S::A; //~ ERROR no associated item named `A` found for type `S` in the current scope - | ^^^^ associated item not found in `S` + | ---^ + | | + | associated item not found in `S` | = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `A`, perhaps you need to implement it: candidate #1: `assoc_const::A` error[E0599]: no associated item named `B` found for type `S` in the current scope - --> $DIR/trait-item-privacy.rs:98:5 + --> $DIR/trait-item-privacy.rs:98:8 | LL | struct S; | --------- associated item `B` not found for this ... LL | S::B; //~ ERROR no associated item named `B` found for type `S` in the current scope - | ^^^^ associated item not found in `S` + | ---^ + | | + | associated item not found in `S` | = help: items from traits can only be used if the trait is in scope help: the following trait is implemented but not in scope, perhaps add a `use` for it: diff --git a/src/test/ui/ufcs/ufcs-partially-resolved.stderr b/src/test/ui/ufcs/ufcs-partially-resolved.stderr index 0297d883b8c59..a576fdde1173e 100644 --- a/src/test/ui/ufcs/ufcs-partially-resolved.stderr +++ b/src/test/ui/ufcs/ufcs-partially-resolved.stderr @@ -187,16 +187,20 @@ LL | let _: ::Y::NN; //~ ERROR ambiguous associated type | ^^^^^^^^^^^^^^^^^ help: use fully-qualified syntax: `<::Y as Trait>::NN` error[E0599]: no associated item named `NN` found for type `::Y` in the current scope - --> $DIR/ufcs-partially-resolved.rs:38:5 + --> $DIR/ufcs-partially-resolved.rs:38:20 | LL | ::Y::NN; //~ ERROR no associated item named `NN` found for type `::Y` - | ^^^^^^^^^^^^^^^^^ associated item not found in `::Y` + | ---------------^^ + | | + | associated item not found in `::Y` error[E0599]: no associated item named `N` found for type `::X` in the current scope - --> $DIR/ufcs-partially-resolved.rs:55:5 + --> $DIR/ufcs-partially-resolved.rs:55:20 | LL | ::X::N; //~ ERROR no associated item named `N` found for type `::X` - | ^^^^^^^^^^^^^^^^ associated item not found in `::X` + | ---------------^ + | | + | associated item not found in `::X` error: aborting due to 32 previous errors diff --git a/src/test/ui/unspecified-self-in-trait-ref.stderr b/src/test/ui/unspecified-self-in-trait-ref.stderr index cb7ee93338f68..b295b39d33c1d 100644 --- a/src/test/ui/unspecified-self-in-trait-ref.stderr +++ b/src/test/ui/unspecified-self-in-trait-ref.stderr @@ -1,26 +1,34 @@ error[E0599]: no function or associated item named `lol` found for type `dyn Foo<_>` in the current scope - --> $DIR/unspecified-self-in-trait-ref.rs:10:13 + --> $DIR/unspecified-self-in-trait-ref.rs:10:18 | LL | let a = Foo::lol(); - | ^^^^^^^^ function or associated item not found in `dyn Foo<_>` + | -----^^^ + | | + | function or associated item not found in `dyn Foo<_>` error[E0599]: no function or associated item named `lol` found for type `dyn Foo<_>` in the current scope - --> $DIR/unspecified-self-in-trait-ref.rs:12:13 + --> $DIR/unspecified-self-in-trait-ref.rs:12:23 | LL | let b = Foo::<_>::lol(); - | ^^^^^^^^^^^^^ function or associated item not found in `dyn Foo<_>` + | ----------^^^ + | | + | function or associated item not found in `dyn Foo<_>` error[E0599]: no function or associated item named `lol` found for type `dyn Bar<_, _>` in the current scope - --> $DIR/unspecified-self-in-trait-ref.rs:14:13 + --> $DIR/unspecified-self-in-trait-ref.rs:14:18 | LL | let c = Bar::lol(); - | ^^^^^^^^ function or associated item not found in `dyn Bar<_, _>` + | -----^^^ + | | + | function or associated item not found in `dyn Bar<_, _>` error[E0599]: no function or associated item named `lol` found for type `dyn Bar` in the current scope - --> $DIR/unspecified-self-in-trait-ref.rs:16:13 + --> $DIR/unspecified-self-in-trait-ref.rs:16:30 | LL | let d = Bar::::lol(); - | ^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `dyn Bar` + | -----------------^^^ + | | + | function or associated item not found in `dyn Bar` error[E0393]: the type parameter `A` must be explicitly specified --> $DIR/unspecified-self-in-trait-ref.rs:18:13 From 74f233388a0ce8c1e5cdf84f6895fb9074c3cabd Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 3 Dec 2018 01:08:41 +0000 Subject: [PATCH 07/22] Added chapter to Unstable Book. --- .../type-alias-enum-variants.md | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 src/doc/unstable-book/src/language-features/type-alias-enum-variants.md diff --git a/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md b/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md new file mode 100644 index 0000000000000..bcdeafc4b1137 --- /dev/null +++ b/src/doc/unstable-book/src/language-features/type-alias-enum-variants.md @@ -0,0 +1,36 @@ +# `type_alias_enum_variants` + +The tracking issue for this feature is: [#49683] + +[#49683]: https://github.com/rust-lang/rust/issues/49683 + +------------------------ + +The `type_alias_enum_variants` feature enables the use of variants on type +aliases that refer to enums, as both a constructor and a pattern. That is, +it allows for the syntax `EnumAlias::Variant`, which behaves exactly the same +as `Enum::Variant` (assuming that `EnumAlias` is an alias for some enum type +`Enum`). + +Note that since `Self` exists as a type alias, this feature also enables the +use of the syntax `Self::Variant` within an impl block for an enum type. + +```rust +#![feature(type_alias_enum_variants)] + +enum Foo { + Bar(i32), + Baz { i: i32 }, +} + +type Alias = Foo; + +fn main() { + let t = Alias::Bar(0); + let t = Alias::Baz { i: 0 }; + match t { + Alias::Bar(_i) => {} + Alias::Baz { i: _i } => {} + } +} +``` From 6a2a7edc0b3f3e296531a6b70a4d89a261bcfeb5 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 6 Dec 2018 04:22:56 +0000 Subject: [PATCH 08/22] Fixed issues raised in first review. --- src/librustc_typeck/astconv.rs | 17 ++++--- src/librustc_typeck/check/method/mod.rs | 12 ++--- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/lib.rs | 33 +++++-------- .../feature-gate-type_alias_enum_variants.rs | 4 -- ...ature-gate-type_alias_enum_variants.stderr | 46 ++----------------- 7 files changed, 33 insertions(+), 85 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 67f330536b85e..f15a27fbc8b59 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -31,7 +31,7 @@ use std::collections::BTreeSet; use std::iter; use std::slice; -use super::{allow_type_alias_enum_variants}; +use super::{check_type_alias_enum_variants_enabled}; pub trait AstConv<'gcx, 'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>; @@ -1277,7 +1277,6 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { ref_id: ast::NodeId, span: Span, ty: Ty<'tcx>, - qself: &hir::Ty, ty_path_def: Def, item_segment: &hir::PathSegment) -> (Ty<'tcx>, Def) @@ -1296,10 +1295,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) }); if let Some(variant_def) = variant_def { - if allow_type_alias_enum_variants(tcx, qself, span) { - let def = Def::Variant(variant_def.did); - return (ty, def); - } + check_type_alias_enum_variants_enabled(tcx, span); + + let def = Def::Variant(variant_def.did); + tcx.check_stability(def.def_id(), Some(ref_id), span); + return (ty, def); } } } @@ -1376,8 +1376,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let item = tcx.associated_items(trait_did).find(|i| { Namespace::from(i.kind) == Namespace::Type && i.ident.modern() == assoc_ident - }) - .expect("missing associated type"); + }).expect("missing associated type"); let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, bound); let ty = self.normalize_ty(span, ty); @@ -1618,7 +1617,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } else { Def::Err }; - self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, qself, def, segment).0 + self.associated_path_def_to_ty(ast_ty.id, ast_ty.span, ty, def, segment).0 } hir::TyKind::Array(ref ty, ref length) => { let length_def_id = tcx.hir().local_def_id(length.id); diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 4c96d476caa22..88814ae6a2db9 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -25,7 +25,7 @@ use rustc::infer::{self, InferOk}; use syntax::ast; use syntax_pos::Span; -use crate::{allow_type_alias_enum_variants}; +use crate::{check_type_alias_enum_variants_enabled}; use self::probe::{IsSuggestion, ProbeScope}; pub fn provide(providers: &mut ty::query::Providers) { @@ -361,7 +361,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { span: Span, method_name: ast::Ident, self_ty: Ty<'tcx>, - qself: &hir::Ty, expr_id: ast::NodeId) -> Result> { debug!("resolve_ufcs: method_name={:?} self_ty={:?} expr_id={:?}", @@ -379,10 +378,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.hygienic_eq(method_name, vd.ident, adt_def.did) }); if let Some(variant_def) = variant_def { - if allow_type_alias_enum_variants(tcx, qself, span) { - let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); - return Ok(def); - } + check_type_alias_enum_variants_enabled(tcx, span); + + let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); + tcx.check_stability(def.def_id(), Some(expr_id), span); + return Ok(def); } } } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index b368250b32d97..98c425655d2d3 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -645,7 +645,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn type_derefs_to_local(&self, span: Span, rcvr_ty: Ty<'tcx>, - rcvr_expr: Option<&hir::Expr>) -> bool { + source: SelfSource) -> bool { fn is_local(ty: Ty) -> bool { match ty.sty { ty::Adt(def, _) => def.did.is_local(), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 37739eb655fb3..b13c92c7f6e7c 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4539,7 +4539,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Def::Err }; let (ty, def) = AstConv::associated_path_def_to_ty(self, node_id, path_span, - ty, qself, def, segment); + ty, def, segment); // Write back the new resolution. let hir_id = self.tcx.hir().node_to_hir_id(node_id); @@ -4575,7 +4575,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { return (*cached_def, Some(ty), slice::from_ref(&**item_segment)) } let item_name = item_segment.ident; - let def = match self.resolve_ufcs(span, item_name, ty, qself, node_id) { + let def = match self.resolve_ufcs(span, item_name, ty, node_id) { Ok(def) => def, Err(error) => { let def = match error { diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 8c0913a56b514..c55a1258ce955 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -105,7 +105,6 @@ mod outlives; mod variance; use hir::Node; -use hir::def::Def; use rustc_target::spec::abi::Abi; use rustc::hir; use rustc::infer::InferOk; @@ -131,28 +130,20 @@ pub struct TypeAndSubsts<'tcx> { ty: Ty<'tcx>, } -fn allow_type_alias_enum_variants<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, - qself: &hir::Ty, - span: Span) -> bool { - let allow_feature = tcx.features().type_alias_enum_variants; - if !allow_feature { - // Only print error if we know the type is an alias. - if let hir::TyKind::Path(hir::QPath::Resolved(None, ref path)) = qself.node { - if let Def::TyAlias(_) = path.def { - let mut err = tcx.sess.struct_span_err( - span, - "enum variants on type aliases are experimental" - ); - if nightly_options::is_nightly_build() { - help!(&mut err, - "add `#![feature(type_alias_enum_variants)]` to the \ - crate attributes to enable"); - } - err.emit(); - } +fn check_type_alias_enum_variants_enabled<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + span: Span) { + if !tcx.features().type_alias_enum_variants { + let mut err = tcx.sess.struct_span_err( + span, + "enum variants on type aliases are experimental" + ); + if nightly_options::is_nightly_build() { + help!(&mut err, + "add `#![feature(type_alias_enum_variants)]` to the \ + crate attributes to enable"); } + err.emit(); } - allow_feature } fn require_c_abi_if_variadic(tcx: TyCtxt, diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs index 2dcd0dcd24381..8997c1824ca6d 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs +++ b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.rs @@ -18,16 +18,12 @@ type Alias = Foo; fn main() { let t = Alias::Bar(0); //~^ ERROR enum variants on type aliases are experimental - //~^^ ERROR no variant named `Bar` found for type `Foo` in the current scope let t = Alias::Baz { i: 0 }; //~^ ERROR enum variants on type aliases are experimental - //~^^ ERROR ambiguous associated type match t { Alias::Bar(_i) => {} //~^ ERROR enum variants on type aliases are experimental - //~^^ ERROR no variant named `Bar` found for type `Foo` in the current scope Alias::Baz { i: _i } => {} //~^ ERROR enum variants on type aliases are experimental - //~^^ ERROR ambiguous associated type } } diff --git a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr index 7a49770d97a2f..cba643e18ca1a 100644 --- a/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr +++ b/src/test/ui/feature-gates/feature-gate-type_alias_enum_variants.stderr @@ -6,67 +6,29 @@ LL | let t = Alias::Bar(0); | = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable -error[E0599]: no variant named `Bar` found for type `Foo` in the current scope - --> $DIR/feature-gate-type_alias_enum_variants.rs:19:20 - | -LL | enum Foo { - | -------- variant `Bar` not found here -... -LL | let t = Alias::Bar(0); - | -------^^^ - | | - | variant not found in `Foo` - | - = help: did you mean `Bar`? - error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:22:13 + --> $DIR/feature-gate-type_alias_enum_variants.rs:21:13 | LL | let t = Alias::Baz { i: 0 }; | ^^^^^^^^^^ | = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable -error[E0223]: ambiguous associated type - --> $DIR/feature-gate-type_alias_enum_variants.rs:22:13 - | -LL | let t = Alias::Baz { i: 0 }; - | ^^^^^^^^^^ help: use fully-qualified syntax: `::Baz` - error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:26:9 + --> $DIR/feature-gate-type_alias_enum_variants.rs:24:9 | LL | Alias::Bar(_i) => {} | ^^^^^^^^^^^^^^ | = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable -error[E0599]: no variant named `Bar` found for type `Foo` in the current scope - --> $DIR/feature-gate-type_alias_enum_variants.rs:26:16 - | -LL | enum Foo { - | -------- variant `Bar` not found here -... -LL | Alias::Bar(_i) => {} - | -------^^^---- variant not found in `Foo` - | - = help: did you mean `Bar`? - error: enum variants on type aliases are experimental - --> $DIR/feature-gate-type_alias_enum_variants.rs:29:9 + --> $DIR/feature-gate-type_alias_enum_variants.rs:26:9 | LL | Alias::Baz { i: _i } => {} | ^^^^^^^^^^ | = help: add `#![feature(type_alias_enum_variants)]` to the crate attributes to enable -error[E0223]: ambiguous associated type - --> $DIR/feature-gate-type_alias_enum_variants.rs:29:9 - | -LL | Alias::Baz { i: _i } => {} - | ^^^^^^^^^^ help: use fully-qualified syntax: `::Baz` - -error: aborting due to 8 previous errors +error: aborting due to 4 previous errors -Some errors occurred: E0223, E0599. -For more information about an error, try `rustc --explain E0223`. From edabad64b022a53c1166ba226d5ce1b3dbd53220 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Fri, 7 Dec 2018 02:12:49 +0000 Subject: [PATCH 09/22] Work-around for shadowing of variant names with assoc const names in `libproc_macro/bridge/rpc.rs`. --- src/libproc_macro/bridge/rpc.rs | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/src/libproc_macro/bridge/rpc.rs b/src/libproc_macro/bridge/rpc.rs index 6685aa1acac39..74ae711a47372 100644 --- a/src/libproc_macro/bridge/rpc.rs +++ b/src/libproc_macro/bridge/rpc.rs @@ -71,15 +71,18 @@ macro_rules! rpc_encode_decode { (enum $name:ident $(<$($T:ident),+>)* { $($variant:ident $(($field:ident))*),* $(,)* }) => { impl),+)*> Encode for $name $(<$($T),+>)* { fn encode(self, w: &mut Writer, s: &mut S) { - // HACK(eddyb) `Tag` enum duplicated between the + // HACK(eddyb): `Tag` enum duplicated between the // two impls as there's no other place to stash it. - #[repr(u8)] enum Tag { $($variant),* } #[allow(non_upper_case_globals)] - impl Tag { $(const $variant: u8 = Tag::$variant as u8;)* } + mod tag { + #[repr(u8)] enum Tag { $($variant),* } + + $(pub const $variant: u8 = Tag::$variant as u8;)* + } match self { $($name::$variant $(($field))* => { - ::$variant.encode(w, s); + tag::$variant.encode(w, s); $($field.encode(w, s);)* })* } @@ -90,14 +93,17 @@ macro_rules! rpc_encode_decode { for $name $(<$($T),+>)* { fn decode(r: &mut Reader<'a>, s: &mut S) -> Self { - // HACK(eddyb) `Tag` enum duplicated between the + // HACK(eddyb): `Tag` enum duplicated between the // two impls as there's no other place to stash it. - #[repr(u8)] enum Tag { $($variant),* } #[allow(non_upper_case_globals)] - impl Tag { $(const $variant: u8 = Tag::$variant as u8;)* } + mod tag { + #[repr(u8)] enum Tag { $($variant),* } + + $(pub const $variant: u8 = Tag::$variant as u8;)* + } match u8::decode(r, s) { - $(::$variant => { + $(tag::$variant => { $(let $field = DecodeMut::decode(r, s);)* $name::$variant $(($field))* })* From 248dbbdffa842f3be4880c5dd016515d3c099f40 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 13 Dec 2018 16:46:34 +0000 Subject: [PATCH 10/22] Added tests for enums & enum aliases with various combinations of generic args. --- src/test/run-pass/enum-generic-args.rs | 34 +++++++++++++ src/test/ui/enum-generic-args.rs | 35 +++++++++++++ src/test/ui/enum-generic-args.stderr | 70 ++++++++++++++++++++++++++ 3 files changed, 139 insertions(+) create mode 100644 src/test/run-pass/enum-generic-args.rs create mode 100644 src/test/ui/enum-generic-args.rs create mode 100644 src/test/ui/enum-generic-args.stderr diff --git a/src/test/run-pass/enum-generic-args.rs b/src/test/run-pass/enum-generic-args.rs new file mode 100644 index 0000000000000..f8cac550b41b6 --- /dev/null +++ b/src/test/run-pass/enum-generic-args.rs @@ -0,0 +1,34 @@ +#![feature(irrefutable_let_patterns)] +#![feature(type_alias_enum_variants)] + +#![allow(irrefutable_let_patterns)] + +enum Enum { Variant(T) } +type Alias = Enum; +type AliasFixed = Enum<()>; + +macro_rules! is_variant { + ($expr:expr) => ( + assert!(if let Enum::Variant::<()>(_) = $expr { true } else { false }, + "expr does not have correct type"); + ) +} + +impl Enum { + fn foo() { + is_variant!(Self::Variant(())); + } +} + +fn main() { + is_variant!(Enum::Variant(())); + is_variant!(Enum::Variant::<()>(())); + is_variant!(Enum::<()>::Variant(())); + + is_variant!(Alias::Variant(())); + is_variant!(Alias::<()>::Variant(())); + + is_variant!(AliasFixed::Variant(())); + + Enum::<()>::foo(); +} diff --git a/src/test/ui/enum-generic-args.rs b/src/test/ui/enum-generic-args.rs new file mode 100644 index 0000000000000..21378b044e1b6 --- /dev/null +++ b/src/test/ui/enum-generic-args.rs @@ -0,0 +1,35 @@ +#![feature(type_alias_enum_variants)] + +enum Enum { Variant(T) } +type Alias = Enum; +type AliasFixed = Enum<()>; + +impl Enum { + fn foo() { + Self::Variant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + Self::<()>::Variant(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + Self::<()>::Variant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + //~^^ ERROR type parameters are not allowed on this type [E0109] + } +} + +fn main() { + Enum::<()>::Variant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + + Alias::Variant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + Alias::<()>::Variant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + + AliasFixed::Variant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + AliasFixed::<()>::Variant(()); + //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] + AliasFixed::<()>::Variant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] +} diff --git a/src/test/ui/enum-generic-args.stderr b/src/test/ui/enum-generic-args.stderr new file mode 100644 index 0000000000000..0807ee15dc757 --- /dev/null +++ b/src/test/ui/enum-generic-args.stderr @@ -0,0 +1,70 @@ +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-generic-args.rs:9:25 + | +LL | Self::Variant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-generic-args.rs:11:16 + | +LL | Self::<()>::Variant(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-generic-args.rs:13:16 + | +LL | Self::<()>::Variant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-generic-args.rs:13:31 + | +LL | Self::<()>::Variant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-generic-args.rs:20:27 + | +LL | Enum::<()>::Variant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-generic-args.rs:23:22 + | +LL | Alias::Variant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-generic-args.rs:25:28 + | +LL | Alias::<()>::Variant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-generic-args.rs:28:27 + | +LL | AliasFixed::Variant::<()>(()); + | ^^ type parameter not allowed + +error[E0107]: wrong number of type arguments: expected 0, found 1 + --> $DIR/enum-generic-args.rs:30:18 + | +LL | AliasFixed::<()>::Variant(()); + | ^^ unexpected type argument + +error[E0107]: wrong number of type arguments: expected 0, found 1 + --> $DIR/enum-generic-args.rs:32:18 + | +LL | AliasFixed::<()>::Variant::<()>(()); + | ^^ unexpected type argument + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-generic-args.rs:32:33 + | +LL | AliasFixed::<()>::Variant::<()>(()); + | ^^ type parameter not allowed + +error: aborting due to 11 previous errors + +Some errors occurred: E0107, E0109. +For more information about an error, try `rustc --explain E0107`. From 66409e03346c23859a5ee0ff78ff44673725553e Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 15 Dec 2018 04:40:09 +0000 Subject: [PATCH 11/22] Fixed issues raised in review. --- src/librustc_typeck/check/mod.rs | 49 ++++++++++++-------------------- 1 file changed, 18 insertions(+), 31 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index b13c92c7f6e7c..f1bcbf3b6b8a4 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5057,7 +5057,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Luckily, we can (at least for now) deduce the intermediate steps // just from the end-point. // - // There are basically four cases to consider: + // There are basically five cases to consider: // // 1. Reference to a constructor of a struct: // @@ -5119,37 +5119,27 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Case 2. Reference to a variant constructor. Def::VariantCtor(def_id, ..) => { - if self.tcx.features().type_alias_enum_variants { - let adt_def = self_ty.and_then(|t| t.ty_adt_def()); - let (generics_def_id, index) = if let Some(adt_def) = adt_def { - debug_assert!(adt_def.is_enum()); - (adt_def.did, last) - } else if last >= 1 && segments[last - 1].args.is_some() { - // Everything but the penultimate segment should have no - // parameters at all. - let enum_def_id = self.tcx.parent_def_id(def_id).unwrap(); - (enum_def_id, last - 1) - } else { - // FIXME: lint here suggesting `Enum::<...>::Variant` form - // instead of `Enum::Variant::<...>` form. - - // Everything but the final segment should have no - // parameters at all. - let generics = self.tcx.generics_of(def_id); - // Variant and struct constructors use the - // generics of their parent type definition. - (generics.parent.unwrap_or(def_id), last) - }; - path_segs.push(PathSeg(generics_def_id, index)); + let adt_def = self_ty.and_then(|t| t.ty_adt_def()); + let (generics_def_id, index) = if let Some(adt_def) = adt_def { + debug_assert!(adt_def.is_enum()); + (adt_def.did, last) + } else if last >= 1 && segments[last - 1].args.is_some() { + // Everything but the penultimate segment should have no + // parameters at all. + let enum_def_id = self.tcx.parent_def_id(def_id).unwrap(); + (enum_def_id, last - 1) } else { + // FIXME: lint here suggesting `Enum::<...>::Variant` form + // instead of `Enum::Variant::<...>` form. + // Everything but the final segment should have no // parameters at all. let generics = self.tcx.generics_of(def_id); // Variant and struct constructors use the // generics of their parent type definition. - let generics_def_id = generics.parent.unwrap_or(def_id); - path_segs.push(PathSeg(generics_def_id, last)); - } + (generics.parent.unwrap_or(def_id), last) + }; + path_segs.push(PathSeg(generics_def_id, index)); } // Case 3. Reference to a top-level value. @@ -5234,14 +5224,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // provided (if any) into their appropriate spaces. We'll also report // errors if type parameters are provided in an inappropriate place. - let is_alias_variant_ctor = if tcx.features().type_alias_enum_variants { + let is_alias_variant_ctor = match def { Def::VariantCtor(_, _) if self_ty.is_some() => true, _ => false, - } - } else { - false - }; + }; let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect(); AstConv::prohibit_generics(self, segments.iter().enumerate().filter_map(|(index, seg)| { From 37e7f0a629db70e19646c8322f3d3b18444577e1 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 15 Dec 2018 14:48:52 +0000 Subject: [PATCH 12/22] Expanded tests for enum variants with generic args. --- src/test/run-pass/enum-generic-args.rs | 34 --- .../run-pass/enum-variant-generic-args.rs | 55 ++++ .../run-pass/type-alias-enum-variants-2.rs | 30 ++ src/test/ui/enum-generic-args.rs | 35 --- src/test/ui/enum-generic-args.stderr | 70 ----- src/test/ui/enum-variant-generic-args.rs | 65 +++++ src/test/ui/enum-variant-generic-args.stderr | 259 ++++++++++++++++++ src/test/ui/type-alias-enum-variants-panic.rs | 10 + 8 files changed, 419 insertions(+), 139 deletions(-) delete mode 100644 src/test/run-pass/enum-generic-args.rs create mode 100644 src/test/run-pass/enum-variant-generic-args.rs create mode 100644 src/test/run-pass/type-alias-enum-variants-2.rs delete mode 100644 src/test/ui/enum-generic-args.rs delete mode 100644 src/test/ui/enum-generic-args.stderr create mode 100644 src/test/ui/enum-variant-generic-args.rs create mode 100644 src/test/ui/enum-variant-generic-args.stderr create mode 100644 src/test/ui/type-alias-enum-variants-panic.rs diff --git a/src/test/run-pass/enum-generic-args.rs b/src/test/run-pass/enum-generic-args.rs deleted file mode 100644 index f8cac550b41b6..0000000000000 --- a/src/test/run-pass/enum-generic-args.rs +++ /dev/null @@ -1,34 +0,0 @@ -#![feature(irrefutable_let_patterns)] -#![feature(type_alias_enum_variants)] - -#![allow(irrefutable_let_patterns)] - -enum Enum { Variant(T) } -type Alias = Enum; -type AliasFixed = Enum<()>; - -macro_rules! is_variant { - ($expr:expr) => ( - assert!(if let Enum::Variant::<()>(_) = $expr { true } else { false }, - "expr does not have correct type"); - ) -} - -impl Enum { - fn foo() { - is_variant!(Self::Variant(())); - } -} - -fn main() { - is_variant!(Enum::Variant(())); - is_variant!(Enum::Variant::<()>(())); - is_variant!(Enum::<()>::Variant(())); - - is_variant!(Alias::Variant(())); - is_variant!(Alias::<()>::Variant(())); - - is_variant!(AliasFixed::Variant(())); - - Enum::<()>::foo(); -} diff --git a/src/test/run-pass/enum-variant-generic-args.rs b/src/test/run-pass/enum-variant-generic-args.rs new file mode 100644 index 0000000000000..bb4a4c9cf0c0c --- /dev/null +++ b/src/test/run-pass/enum-variant-generic-args.rs @@ -0,0 +1,55 @@ +#![feature(irrefutable_let_patterns)] +#![feature(type_alias_enum_variants)] + +#![allow(irrefutable_let_patterns)] + +enum Enum { TSVariant(T), SVariant { v: T } } +type Alias = Enum; +type AliasFixed = Enum<()>; + +macro_rules! is_variant { + (TSVariant, $expr:expr) => (is_variant!(@TSVariant, (_), $expr)); + (SVariant, $expr:expr) => (is_variant!(@SVariant, { v: _ }, $expr)); + (@$variant:ident, $matcher:tt, $expr:expr) => ( + assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false }, + "expr does not have correct type"); + ); +} + +impl Enum { + fn ts_variant() { + is_variant!(TSVariant, Self::TSVariant(())); + } + + fn s_variant() { + is_variant!(SVariant, Self::SVariant { v: () }); + } +} + +fn main() { + // Tuple struct variant + + is_variant!(TSVariant, Enum::TSVariant(())); + is_variant!(TSVariant, Enum::TSVariant::<()>(())); + is_variant!(TSVariant, Enum::<()>::TSVariant(())); + + is_variant!(TSVariant, Alias::TSVariant(())); + is_variant!(TSVariant, Alias::<()>::TSVariant(())); + + is_variant!(TSVariant, AliasFixed::TSVariant(())); + + Enum::<()>::ts_variant(); + + // Struct variant + + is_variant!(SVariant, Enum::SVariant { v: () }); + is_variant!(SVariant, Enum::SVariant::<()> { v: () }); + is_variant!(SVariant, Enum::<()>::SVariant { v: () }); + + is_variant!(SVariant, Alias::SVariant { v: () }); + is_variant!(SVariant, Alias::<()>::SVariant { v: () }); + + is_variant!(SVariant, AliasFixed::SVariant { v: () }); + + Enum::<()>::s_variant(); +} diff --git a/src/test/run-pass/type-alias-enum-variants-2.rs b/src/test/run-pass/type-alias-enum-variants-2.rs new file mode 100644 index 0000000000000..0cf413babcbf6 --- /dev/null +++ b/src/test/run-pass/type-alias-enum-variants-2.rs @@ -0,0 +1,30 @@ +#![feature(type_alias_enum_variants)] + +#[derive(Debug, PartialEq, Eq)] +enum Foo { + Bar(i32), + Baz { i: i32 }, +} + +type FooAlias = Foo; +type OptionAlias = Option; + +impl Foo { + fn foo() -> Self { + Self::Bar(3) + } +} + +fn main() { + let t = FooAlias::Bar(1); + assert_eq!(t, Foo::Bar(1)); + let t = FooAlias::Baz { i: 2 }; + assert_eq!(t, Foo::Baz { i: 2 }); + match t { + FooAlias::Bar(_i) => {} + FooAlias::Baz { i } => { assert_eq!(i, 2); } + } + assert_eq!(Foo::foo(), Foo::Bar(3)); + + assert_eq!(OptionAlias::Some(4), Option::Some(4)); +} diff --git a/src/test/ui/enum-generic-args.rs b/src/test/ui/enum-generic-args.rs deleted file mode 100644 index 21378b044e1b6..0000000000000 --- a/src/test/ui/enum-generic-args.rs +++ /dev/null @@ -1,35 +0,0 @@ -#![feature(type_alias_enum_variants)] - -enum Enum { Variant(T) } -type Alias = Enum; -type AliasFixed = Enum<()>; - -impl Enum { - fn foo() { - Self::Variant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - Self::<()>::Variant(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - Self::<()>::Variant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - //~^^ ERROR type parameters are not allowed on this type [E0109] - } -} - -fn main() { - Enum::<()>::Variant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - - Alias::Variant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - Alias::<()>::Variant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - - AliasFixed::Variant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - AliasFixed::<()>::Variant(()); - //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] - AliasFixed::<()>::Variant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] -} diff --git a/src/test/ui/enum-generic-args.stderr b/src/test/ui/enum-generic-args.stderr deleted file mode 100644 index 0807ee15dc757..0000000000000 --- a/src/test/ui/enum-generic-args.stderr +++ /dev/null @@ -1,70 +0,0 @@ -error[E0109]: type parameters are not allowed on this type - --> $DIR/enum-generic-args.rs:9:25 - | -LL | Self::Variant::<()>(()); - | ^^ type parameter not allowed - -error[E0109]: type parameters are not allowed on this type - --> $DIR/enum-generic-args.rs:11:16 - | -LL | Self::<()>::Variant(()); - | ^^ type parameter not allowed - -error[E0109]: type parameters are not allowed on this type - --> $DIR/enum-generic-args.rs:13:16 - | -LL | Self::<()>::Variant::<()>(()); - | ^^ type parameter not allowed - -error[E0109]: type parameters are not allowed on this type - --> $DIR/enum-generic-args.rs:13:31 - | -LL | Self::<()>::Variant::<()>(()); - | ^^ type parameter not allowed - -error[E0109]: type parameters are not allowed on this type - --> $DIR/enum-generic-args.rs:20:27 - | -LL | Enum::<()>::Variant::<()>(()); - | ^^ type parameter not allowed - -error[E0109]: type parameters are not allowed on this type - --> $DIR/enum-generic-args.rs:23:22 - | -LL | Alias::Variant::<()>(()); - | ^^ type parameter not allowed - -error[E0109]: type parameters are not allowed on this type - --> $DIR/enum-generic-args.rs:25:28 - | -LL | Alias::<()>::Variant::<()>(()); - | ^^ type parameter not allowed - -error[E0109]: type parameters are not allowed on this type - --> $DIR/enum-generic-args.rs:28:27 - | -LL | AliasFixed::Variant::<()>(()); - | ^^ type parameter not allowed - -error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-generic-args.rs:30:18 - | -LL | AliasFixed::<()>::Variant(()); - | ^^ unexpected type argument - -error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-generic-args.rs:32:18 - | -LL | AliasFixed::<()>::Variant::<()>(()); - | ^^ unexpected type argument - -error[E0109]: type parameters are not allowed on this type - --> $DIR/enum-generic-args.rs:32:33 - | -LL | AliasFixed::<()>::Variant::<()>(()); - | ^^ type parameter not allowed - -error: aborting due to 11 previous errors - -Some errors occurred: E0107, E0109. -For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/enum-variant-generic-args.rs b/src/test/ui/enum-variant-generic-args.rs new file mode 100644 index 0000000000000..37109e89624b0 --- /dev/null +++ b/src/test/ui/enum-variant-generic-args.rs @@ -0,0 +1,65 @@ +#![feature(type_alias_enum_variants)] + +enum Enum { TSVariant(T), SVariant { v: T } } +type Alias = Enum; +type AliasFixed = Enum<()>; + +impl Enum { + fn ts_variant() { + Self::TSVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + Self::<()>::TSVariant(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + Self::<()>::TSVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + //~^^ ERROR type parameters are not allowed on this type [E0109] + } + + fn s_variant() { + Self::SVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + Self::<()>::SVariant(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + Self::<()>::SVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + //~^^ ERROR type parameters are not allowed on this type [E0109] + } +} + +fn main() { + // Tuple struct variant + + Enum::<()>::TSVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + + Alias::TSVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + Alias::<()>::TSVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + + AliasFixed::TSVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + AliasFixed::<()>::TSVariant(()); + //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] + AliasFixed::<()>::TSVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] + + // Struct variant + + Enum::<()>::SVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + + Alias::SVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + Alias::<()>::SVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + + AliasFixed::SVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + AliasFixed::<()>::SVariant(()); + //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] + AliasFixed::<()>::SVariant::<()>(()); + //~^ ERROR type parameters are not allowed on this type [E0109] + //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] +} diff --git a/src/test/ui/enum-variant-generic-args.stderr b/src/test/ui/enum-variant-generic-args.stderr new file mode 100644 index 0000000000000..4cae164b6ff46 --- /dev/null +++ b/src/test/ui/enum-variant-generic-args.stderr @@ -0,0 +1,259 @@ +error[E0423]: expected function, found struct variant `Enum::SVariant` + --> $DIR/enum-variant-generic-args.rs:50:5 + | +LL | Enum::<()>::SVariant::<()>(()); + | ^^^^^^^^^^^^--------^^^^^^ + | | | + | | did you mean `TSVariant`? + | did you mean `Enum::SVariant { /* fields */ }`? + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:9:27 + | +LL | Self::TSVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:11:16 + | +LL | Self::<()>::TSVariant(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:13:16 + | +LL | Self::<()>::TSVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:13:33 + | +LL | Self::<()>::TSVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:19:26 + | +LL | Self::SVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0618]: expected function, found enum variant `::SVariant::<()>` + --> $DIR/enum-variant-generic-args.rs:19:9 + | +LL | enum Enum { TSVariant(T), SVariant { v: T } } + | ----------------- `::SVariant::<()>` defined here +... +LL | Self::SVariant::<()>(()); + | ^^^^^^^^^^^^^^^^^^^^---- + | | + | call expression requires function +help: `::SVariant::<()>` is a unit variant, you need to write it without the parenthesis + | +LL | ::SVariant::<()>; + | ^^^^^^^^^^^^^^^^^^^^^^ + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:21:16 + | +LL | Self::<()>::SVariant(()); + | ^^ type parameter not allowed + +error[E0618]: expected function, found enum variant `>::SVariant` + --> $DIR/enum-variant-generic-args.rs:21:9 + | +LL | enum Enum { TSVariant(T), SVariant { v: T } } + | ----------------- `>::SVariant` defined here +... +LL | Self::<()>::SVariant(()); + | ^^^^^^^^^^^^^^^^^^^^---- + | | + | call expression requires function +help: `>::SVariant` is a unit variant, you need to write it without the parenthesis + | +LL | >::SVariant; + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:23:16 + | +LL | Self::<()>::SVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:23:32 + | +LL | Self::<()>::SVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0618]: expected function, found enum variant `>::SVariant::<()>` + --> $DIR/enum-variant-generic-args.rs:23:9 + | +LL | enum Enum { TSVariant(T), SVariant { v: T } } + | ----------------- `>::SVariant::<()>` defined here +... +LL | Self::<()>::SVariant::<()>(()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^---- + | | + | call expression requires function +help: `>::SVariant::<()>` is a unit variant, you need to write it without the parenthesis + | +LL | >::SVariant::<()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:32:29 + | +LL | Enum::<()>::TSVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:35:24 + | +LL | Alias::TSVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:37:30 + | +LL | Alias::<()>::TSVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:40:29 + | +LL | AliasFixed::TSVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0107]: wrong number of type arguments: expected 0, found 1 + --> $DIR/enum-variant-generic-args.rs:42:18 + | +LL | AliasFixed::<()>::TSVariant(()); + | ^^ unexpected type argument + +error[E0107]: wrong number of type arguments: expected 0, found 1 + --> $DIR/enum-variant-generic-args.rs:44:18 + | +LL | AliasFixed::<()>::TSVariant::<()>(()); + | ^^ unexpected type argument + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:44:35 + | +LL | AliasFixed::<()>::TSVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:53:23 + | +LL | Alias::SVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0618]: expected function, found enum variant `::SVariant::<()>` + --> $DIR/enum-variant-generic-args.rs:53:5 + | +LL | enum Enum { TSVariant(T), SVariant { v: T } } + | ----------------- `::SVariant::<()>` defined here +... +LL | Alias::SVariant::<()>(()); + | ^^^^^^^^^^^^^^^^^^^^^---- + | | + | call expression requires function +help: `::SVariant::<()>` is a unit variant, you need to write it without the parenthesis + | +LL | ::SVariant::<()>; + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:55:29 + | +LL | Alias::<()>::SVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0618]: expected function, found enum variant `>::SVariant::<()>` + --> $DIR/enum-variant-generic-args.rs:55:5 + | +LL | enum Enum { TSVariant(T), SVariant { v: T } } + | ----------------- `>::SVariant::<()>` defined here +... +LL | Alias::<()>::SVariant::<()>(()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^---- + | | + | call expression requires function +help: `>::SVariant::<()>` is a unit variant, you need to write it without the parenthesis + | +LL | >::SVariant::<()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:58:28 + | +LL | AliasFixed::SVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0618]: expected function, found enum variant `::SVariant::<()>` + --> $DIR/enum-variant-generic-args.rs:58:5 + | +LL | enum Enum { TSVariant(T), SVariant { v: T } } + | ----------------- `::SVariant::<()>` defined here +... +LL | AliasFixed::SVariant::<()>(()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^---- + | | + | call expression requires function +help: `::SVariant::<()>` is a unit variant, you need to write it without the parenthesis + | +LL | ::SVariant::<()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0107]: wrong number of type arguments: expected 0, found 1 + --> $DIR/enum-variant-generic-args.rs:60:18 + | +LL | AliasFixed::<()>::SVariant(()); + | ^^ unexpected type argument + +error[E0618]: expected function, found enum variant `>::SVariant` + --> $DIR/enum-variant-generic-args.rs:60:5 + | +LL | enum Enum { TSVariant(T), SVariant { v: T } } + | ----------------- `>::SVariant` defined here +... +LL | AliasFixed::<()>::SVariant(()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^---- + | | + | call expression requires function +help: `>::SVariant` is a unit variant, you need to write it without the parenthesis + | +LL | >::SVariant; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0107]: wrong number of type arguments: expected 0, found 1 + --> $DIR/enum-variant-generic-args.rs:62:18 + | +LL | AliasFixed::<()>::SVariant::<()>(()); + | ^^ unexpected type argument + +error[E0109]: type parameters are not allowed on this type + --> $DIR/enum-variant-generic-args.rs:62:34 + | +LL | AliasFixed::<()>::SVariant::<()>(()); + | ^^ type parameter not allowed + +error[E0618]: expected function, found enum variant `>::SVariant::<()>` + --> $DIR/enum-variant-generic-args.rs:62:5 + | +LL | enum Enum { TSVariant(T), SVariant { v: T } } + | ----------------- `>::SVariant::<()>` defined here +... +LL | AliasFixed::<()>::SVariant::<()>(()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---- + | | + | call expression requires function +help: `>::SVariant::<()>` is a unit variant, you need to write it without the parenthesis + | +LL | >::SVariant::<()>; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to 30 previous errors + +Some errors occurred: E0107, E0109, E0423, E0618. +For more information about an error, try `rustc --explain E0107`. diff --git a/src/test/ui/type-alias-enum-variants-panic.rs b/src/test/ui/type-alias-enum-variants-panic.rs new file mode 100644 index 0000000000000..abed190d22b0c --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-panic.rs @@ -0,0 +1,10 @@ +#![feature(type_alias_enum_variants)] + +enum Enum { Variant {} } +type Alias = Enum; + +fn main() { + Alias::Variant; + let Alias::Variant = panic!(); + let Alias::Variant(..) = panic!(); +} From 65f50582cf3e06e6f6dd68d3e5e5b841ac4ea6e9 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 15 Dec 2018 14:54:33 +0000 Subject: [PATCH 13/22] Removed unnecessary special handling of `VariantCtor` defs in `instantiate_value_path`. --- src/librustc_typeck/check/mod.rs | 16 ---------------- 1 file changed, 16 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f1bcbf3b6b8a4..93d44344a1eac 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5316,22 +5316,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - Def::VariantCtor(_, _) if self_ty.is_some() => { - let def_id = def.def_id(); - - let ty = tcx.type_of(def_id); - if tcx.features().type_alias_enum_variants { - if let Some(self_ty) = self_ty { - match ty.ty_adt_def() { - Some(adt_def) if adt_def.is_enum() => { - return (self_ty, def); - } - _ => {} - } - } - } - (def_id, ty) - } _ => { let def_id = def.def_id(); From 5a36f9e6e1eaf0330e499d15ab428350be837657 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 17 Dec 2018 18:49:45 +0000 Subject: [PATCH 14/22] Fixed several ICEs. --- src/librustc_typeck/check/_match.rs | 14 +- src/librustc_typeck/check/mod.rs | 145 ++++++++++-------- src/test/ui/type-alias-enum-variants-panic.rs | 7 + .../ui/type-alias-enum-variants-panic.stderr | 22 +++ 4 files changed, 116 insertions(+), 72 deletions(-) create mode 100644 src/test/ui/type-alias-enum-variants-panic.stderr diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 4e3cb5c7f1c0d..923be2a76aa66 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -17,6 +17,8 @@ use util::nodemap::FxHashMap; use std::collections::hash_map::Entry::{Occupied, Vacant}; use std::cmp; +use super::report_unexpected_variant_def; + impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { /// The `is_arg` argument indicates whether this pattern is the /// *outermost* pattern in an argument (e.g., in `fn foo(&x: @@ -736,12 +738,6 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); expected: Ty<'tcx>) -> Ty<'tcx> { let tcx = self.tcx; - let report_unexpected_def = |def: Def| { - span_err!(tcx.sess, pat.span, E0533, - "expected unit struct/variant or constant, found {} `{}`", - def.kind_name(), - hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false))); - }; // Resolve the path and check the definition for errors. let (def, opt_ty, segments) = self.resolve_ty_and_def_ufcs(qpath, pat.id, pat.span); @@ -751,7 +747,11 @@ https://doc.rust-lang.org/reference/types.html#trait-objects"); return tcx.types.err; } Def::Method(..) => { - report_unexpected_def(def); + report_unexpected_variant_def(tcx, &def, pat.span, qpath); + return tcx.types.err; + } + Def::VariantCtor(_, CtorKind::Fictive) => { + report_unexpected_variant_def(tcx, &def, pat.span, qpath); return tcx.types.err; } Def::VariantCtor(_, CtorKind::Const) | diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 93d44344a1eac..bf878f87e3693 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -85,8 +85,8 @@ mod op; use astconv::AstConv; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; -use rustc::hir::{self, GenericArg, ItemKind, Node, PatKind}; -use rustc::hir::def::Def; +use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath}; +use rustc::hir::def::{CtorKind, Def}; use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use rustc::hir::intravisit::{self, Visitor, NestedVisitorMap}; use rustc::hir::itemlikevisit::ItemLikeVisitor; @@ -1864,6 +1864,16 @@ pub fn check_enum<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, check_representable(tcx, sp, def_id); } +fn report_unexpected_variant_def<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + def: &Def, + span: Span, + qpath: &QPath) { + span_err!(tcx.sess, span, E0533, + "expected unit struct/variant or constant, found {} `{}`", + def.kind_name(), + hir::print::to_string(tcx.hir(), |s| s.print_qpath(qpath, false))); +} + impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.tcx } @@ -2947,7 +2957,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } let is_closure = match arg.node { - hir::ExprKind::Closure(..) => true, + ExprKind::Closure(..) => true, _ => false }; @@ -3097,8 +3107,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } if let Some(mut err) = self.demand_suptype_diag(expr.span, expected_ty, ty) { - // Add help to type error if this is an `if` condition with an assignment - if let (ExpectIfCondition, &hir::ExprKind::Assign(ref lhs, ref rhs)) + // Add help to type error if this is an `if` condition with an assignment. + if let (ExpectIfCondition, &ExprKind::Assign(ref lhs, ref rhs)) = (expected, &expr.node) { let msg = "try comparing for equality"; @@ -3691,12 +3701,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } pub fn check_struct_path(&self, - qpath: &hir::QPath, + qpath: &QPath, node_id: ast::NodeId) -> Option<(&'tcx ty::VariantDef, Ty<'tcx>)> { let path_span = match *qpath { - hir::QPath::Resolved(_, ref path) => path.span, - hir::QPath::TypeRelative(ref qself, _) => qself.span + QPath::Resolved(_, ref path) => path.span, + QPath::TypeRelative(ref qself, _) => qself.span }; let (def, ty) = self.finish_resolving_struct_path(qpath, path_span, node_id); let variant = match def { @@ -3749,7 +3759,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { fn check_expr_struct(&self, expr: &hir::Expr, expected: Expectation<'tcx>, - qpath: &hir::QPath, + qpath: &QPath, fields: &'gcx [hir::Field], base_expr: &'gcx Option>) -> Ty<'tcx> { @@ -3763,8 +3773,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; let path_span = match *qpath { - hir::QPath::Resolved(_, ref path) => path.span, - hir::QPath::TypeRelative(ref qself, _) => qself.span + QPath::Resolved(_, ref path) => path.span, + QPath::TypeRelative(ref qself, _) => qself.span }; // Prohibit struct expressions when non-exhaustive flag is set. @@ -3836,9 +3846,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Warn for non-block expressions with diverging children. match expr.node { - hir::ExprKind::Block(..) | - hir::ExprKind::Loop(..) | hir::ExprKind::While(..) | - hir::ExprKind::If(..) | hir::ExprKind::Match(..) => {} + ExprKind::Block(..) | + ExprKind::Loop(..) | ExprKind::While(..) | + ExprKind::If(..) | ExprKind::Match(..) => {} _ => self.warn_if_unreachable(expr.id, expr.span, "expression") } @@ -3879,7 +3889,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; let id = expr.id; match expr.node { - hir::ExprKind::Box(ref subexpr) => { + ExprKind::Box(ref subexpr) => { let expected_inner = expected.to_option(self).map_or(NoExpectation, |ty| { match ty.sty { ty::Adt(def, _) if def.is_box() @@ -3891,16 +3901,16 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.mk_box(referent_ty) } - hir::ExprKind::Lit(ref lit) => { + ExprKind::Lit(ref lit) => { self.check_lit(&lit, expected) } - hir::ExprKind::Binary(op, ref lhs, ref rhs) => { + ExprKind::Binary(op, ref lhs, ref rhs) => { self.check_binop(expr, op, lhs, rhs) } - hir::ExprKind::AssignOp(op, ref lhs, ref rhs) => { + ExprKind::AssignOp(op, ref lhs, ref rhs) => { self.check_binop_assign(expr, op, lhs, rhs) } - hir::ExprKind::Unary(unop, ref oprnd) => { + ExprKind::Unary(unop, ref oprnd) => { let expected_inner = match unop { hir::UnNot | hir::UnNeg => { expected @@ -3968,7 +3978,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } oprnd_t } - hir::ExprKind::AddrOf(mutbl, ref oprnd) => { + ExprKind::AddrOf(mutbl, ref oprnd) => { let hint = expected.only_has_type(self).map_or(NoExpectation, |ty| { match ty.sty { ty::Ref(_, ty, _) | ty::RawPtr(ty::TypeAndMut { ty, .. }) => { @@ -4008,13 +4018,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.mk_ref(region, tm) } } - hir::ExprKind::Path(ref qpath) => { + ExprKind::Path(ref qpath) => { let (def, opt_ty, segs) = self.resolve_ty_and_def_ufcs(qpath, expr.id, expr.span); - let ty = if def != Def::Err { - self.instantiate_value_path(segs, opt_ty, def, expr.span, id).0 - } else { - self.set_tainted_by_errors(); - tcx.types.err + let ty = match def { + Def::Err => { + self.set_tainted_by_errors(); + tcx.types.err + } + Def::VariantCtor(_, CtorKind::Fictive) => { + report_unexpected_variant_def(tcx, &def, expr.span, qpath); + tcx.types.err + } + _ => self.instantiate_value_path(segs, opt_ty, def, expr.span, id).0, }; if let ty::FnDef(..) = ty.sty { @@ -4061,13 +4076,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty } - hir::ExprKind::InlineAsm(_, ref outputs, ref inputs) => { + ExprKind::InlineAsm(_, ref outputs, ref inputs) => { for expr in outputs.iter().chain(inputs.iter()) { self.check_expr(expr); } tcx.mk_unit() } - hir::ExprKind::Break(destination, ref expr_opt) => { + ExprKind::Break(destination, ref expr_opt) => { if let Ok(target_id) = destination.target_id { let (e_ty, cause); if let Some(ref e) = *expr_opt { @@ -4140,7 +4155,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // ... except when we try to 'break rust;'. // ICE this expression in particular (see #43162). - if let hir::ExprKind::Path(hir::QPath::Resolved(_, ref path)) = e.node { + if let ExprKind::Path(QPath::Resolved(_, ref path)) = e.node { if path.segments.len() == 1 && path.segments[0].ident.name == "rust" { fatally_break_rust(self.tcx.sess); } @@ -4151,7 +4166,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - hir::ExprKind::Continue(destination) => { + ExprKind::Continue(destination) => { if destination.target_id.is_ok() { tcx.types.never } else { @@ -4159,7 +4174,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.types.err } } - hir::ExprKind::Ret(ref expr_opt) => { + ExprKind::Ret(ref expr_opt) => { if self.ret_coercion.is_none() { struct_span_err!(self.tcx.sess, expr.span, E0572, "return statement outside of function body").emit(); @@ -4191,7 +4206,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } tcx.types.never } - hir::ExprKind::Assign(ref lhs, ref rhs) => { + ExprKind::Assign(ref lhs, ref rhs) => { let lhs_ty = self.check_expr_with_needs(&lhs, Needs::MutPlace); let rhs_ty = self.check_expr_coercable_to_type(&rhs, lhs_ty); @@ -4221,11 +4236,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.mk_unit() } } - hir::ExprKind::If(ref cond, ref then_expr, ref opt_else_expr) => { + ExprKind::If(ref cond, ref then_expr, ref opt_else_expr) => { self.check_then_else(&cond, then_expr, opt_else_expr.as_ref().map(|e| &**e), expr.span, expected) } - hir::ExprKind::While(ref cond, ref body, _) => { + ExprKind::While(ref cond, ref body, _) => { let ctxt = BreakableCtxt { // cannot use break with a value from a while loop coerce: None, @@ -4249,7 +4264,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.tcx.mk_unit() } - hir::ExprKind::Loop(ref body, _, source) => { + ExprKind::Loop(ref body, _, source) => { let coerce = match source { // you can only use break with a value from a normal `loop { }` hir::LoopSource::Loop => { @@ -4289,22 +4304,22 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } ctxt.coerce.map(|c| c.complete(self)).unwrap_or_else(|| self.tcx.mk_unit()) } - hir::ExprKind::Match(ref discrim, ref arms, match_src) => { + ExprKind::Match(ref discrim, ref arms, match_src) => { self.check_match(expr, &discrim, arms, expected, match_src) } - hir::ExprKind::Closure(capture, ref decl, body_id, _, gen) => { + ExprKind::Closure(capture, ref decl, body_id, _, gen) => { self.check_expr_closure(expr, capture, &decl, body_id, gen, expected) } - hir::ExprKind::Block(ref body, _) => { + ExprKind::Block(ref body, _) => { self.check_block_with_expected(&body, expected) } - hir::ExprKind::Call(ref callee, ref args) => { + ExprKind::Call(ref callee, ref args) => { self.check_call(expr, &callee, args, expected) } - hir::ExprKind::MethodCall(ref segment, span, ref args) => { + ExprKind::MethodCall(ref segment, span, ref args) => { self.check_method_call(expr, segment, span, args, expected, needs) } - hir::ExprKind::Cast(ref e, ref t) => { + ExprKind::Cast(ref e, ref t) => { // Find the type of `e`. Supply hints based on the type we are casting to, // if appropriate. let t_cast = self.to_ty_saving_user_provided_ty(t); @@ -4329,12 +4344,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - hir::ExprKind::Type(ref e, ref t) => { + ExprKind::Type(ref e, ref t) => { let ty = self.to_ty_saving_user_provided_ty(&t); self.check_expr_eq_type(&e, ty); ty } - hir::ExprKind::Array(ref args) => { + ExprKind::Array(ref args) => { let uty = expected.to_option(self).and_then(|uty| { match uty.sty { ty::Array(ty, _) | ty::Slice(ty) => Some(ty), @@ -4358,7 +4373,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; tcx.mk_array(element_ty, args.len() as u64) } - hir::ExprKind::Repeat(ref element, ref count) => { + ExprKind::Repeat(ref element, ref count) => { let count_def_id = tcx.hir().local_def_id(count.id); let param_env = ty::ParamEnv::empty(); let substs = Substs::identity_for_item(tcx.global_tcx(), count_def_id); @@ -4414,7 +4429,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.types.err } } - hir::ExprKind::Tup(ref elts) => { + ExprKind::Tup(ref elts) => { let flds = expected.only_has_type(self).and_then(|ty| { let ty = self.resolve_type_vars_with_obligations(ty); match ty.sty { @@ -4444,13 +4459,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tuple } } - hir::ExprKind::Struct(ref qpath, ref fields, ref base_expr) => { + ExprKind::Struct(ref qpath, ref fields, ref base_expr) => { self.check_expr_struct(expr, expected, qpath, fields, base_expr) } - hir::ExprKind::Field(ref base, field) => { + ExprKind::Field(ref base, field) => { self.check_field(expr, needs, &base, field) } - hir::ExprKind::Index(ref base, ref idx) => { + ExprKind::Index(ref base, ref idx) => { let base_t = self.check_expr_with_needs(&base, needs); let idx_t = self.check_expr(&idx); @@ -4476,7 +4491,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let mut needs_note = true; // If the index is an integer, we can show the actual // fixed expression: - if let hir::ExprKind::Lit(ref lit) = idx.node { + if let ExprKind::Lit(ref lit) = idx.node { if let ast::LitKind::Int(i, ast::LitIntType::Unsuffixed) = lit.node { let snip = tcx.sess.source_map().span_to_snippet(base.span); @@ -4501,7 +4516,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } } - hir::ExprKind::Yield(ref value) => { + ExprKind::Yield(ref value) => { match self.yield_ty { Some(ty) => { self.check_expr_coercable_to_type(&value, ty); @@ -4519,21 +4534,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Finish resolving a path in a struct expression or pattern `S::A { .. }` if necessary. // The newly resolved definition is written into `type_dependent_defs`. fn finish_resolving_struct_path(&self, - qpath: &hir::QPath, + qpath: &QPath, path_span: Span, node_id: ast::NodeId) -> (Def, Ty<'tcx>) { match *qpath { - hir::QPath::Resolved(ref maybe_qself, ref path) => { + QPath::Resolved(ref maybe_qself, ref path) => { let self_ty = maybe_qself.as_ref().map(|qself| self.to_ty(qself)); let ty = AstConv::def_to_ty(self, self_ty, path, true); (path.def, ty) } - hir::QPath::TypeRelative(ref qself, ref segment) => { + QPath::TypeRelative(ref qself, ref segment) => { let ty = self.to_ty(qself); - let def = if let hir::TyKind::Path(hir::QPath::Resolved(_, ref path)) = qself.node { + let def = if let hir::TyKind::Path(QPath::Resolved(_, ref path)) = qself.node { path.def } else { Def::Err @@ -4553,18 +4568,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Resolve associated value path into a base type and associated constant or method definition. // The newly resolved definition is written into `type_dependent_defs`. pub fn resolve_ty_and_def_ufcs<'b>(&self, - qpath: &'b hir::QPath, + qpath: &'b QPath, node_id: ast::NodeId, span: Span) -> (Def, Option>, &'b [hir::PathSegment]) { let (ty, qself, item_segment) = match *qpath { - hir::QPath::Resolved(ref opt_qself, ref path) => { + QPath::Resolved(ref opt_qself, ref path) => { return (path.def, opt_qself.as_ref().map(|qself| self.to_ty(qself)), &path.segments[..]); } - hir::QPath::TypeRelative(ref qself, ref segment) => { + QPath::TypeRelative(ref qself, ref segment) => { (self.to_ty(qself), qself, segment) } }; @@ -4935,13 +4950,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // `BlockTailExpression` only relevant if the tail expr would be // useful on its own. match expression.node { - hir::ExprKind::Call(..) | - hir::ExprKind::MethodCall(..) | - hir::ExprKind::If(..) | - hir::ExprKind::While(..) | - hir::ExprKind::Loop(..) | - hir::ExprKind::Match(..) | - hir::ExprKind::Block(..) => { + ExprKind::Call(..) | + ExprKind::MethodCall(..) | + ExprKind::If(..) | + ExprKind::While(..) | + ExprKind::Loop(..) | + ExprKind::Match(..) | + ExprKind::Block(..) => { let sp = self.tcx.sess.source_map().next_point(cause_span); err.span_suggestion_with_applicability( sp, @@ -5449,7 +5464,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // If our calling expression is indeed the function itself, we're good! // If not, generate an error that this can only be called directly. if let Node::Expr(expr) = self.tcx.hir().get(self.tcx.hir().get_parent_node(node_id)) { - if let hir::ExprKind::Call(ref callee, ..) = expr.node { + if let ExprKind::Call(ref callee, ..) = expr.node { if callee.id == node_id { return } diff --git a/src/test/ui/type-alias-enum-variants-panic.rs b/src/test/ui/type-alias-enum-variants-panic.rs index abed190d22b0c..f97592f5d3b15 100644 --- a/src/test/ui/type-alias-enum-variants-panic.rs +++ b/src/test/ui/type-alias-enum-variants-panic.rs @@ -1,10 +1,17 @@ +// ignore-tidy-linelength + #![feature(type_alias_enum_variants)] +#![allow(unreachable_code)] + enum Enum { Variant {} } type Alias = Enum; fn main() { Alias::Variant; + //~^ ERROR expected unit struct/variant or constant, found struct variant `::Variant` [E0533] let Alias::Variant = panic!(); + //~^ ERROR expected unit struct/variant or constant, found struct variant `::Variant` [E0533] let Alias::Variant(..) = panic!(); + //~^ ERROR expected tuple struct/variant, found struct variant `::Variant` [E0164] } diff --git a/src/test/ui/type-alias-enum-variants-panic.stderr b/src/test/ui/type-alias-enum-variants-panic.stderr new file mode 100644 index 0000000000000..3480d116383ee --- /dev/null +++ b/src/test/ui/type-alias-enum-variants-panic.stderr @@ -0,0 +1,22 @@ +error[E0533]: expected unit struct/variant or constant, found struct variant `::Variant` + --> $DIR/type-alias-enum-variants-panic.rs:11:5 + | +LL | Alias::Variant; + | ^^^^^^^^^^^^^^ + +error[E0533]: expected unit struct/variant or constant, found struct variant `::Variant` + --> $DIR/type-alias-enum-variants-panic.rs:13:9 + | +LL | let Alias::Variant = panic!(); + | ^^^^^^^^^^^^^^ + +error[E0164]: expected tuple struct/variant, found struct variant `::Variant` + --> $DIR/type-alias-enum-variants-panic.rs:15:9 + | +LL | let Alias::Variant(..) = panic!(); + | ^^^^^^^^^^^^^^^^^^ not a tuple variant or struct + +error: aborting due to 3 previous errors + +Some errors occurred: E0164, E0533. +For more information about an error, try `rustc --explain E0164`. From 8eb1a9e4e7337dd17827e00f0e1d2e10f11de30c Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Tue, 18 Dec 2018 00:40:22 +0000 Subject: [PATCH 15/22] Added regression test for using generic parameters on modules. --- src/librustc/hir/mod.rs | 2 +- src/librustc_typeck/astconv.rs | 6 +- src/librustc_typeck/diagnostics.rs | 2 +- src/test/ui/enum-variant-generic-args.rs | 36 ++--- src/test/ui/enum-variant-generic-args.stderr | 68 ++++----- src/test/ui/error-codes/E0109.stderr | 4 +- src/test/ui/error-codes/E0110.stderr | 12 +- src/test/ui/issues/issue-22706.rs | 2 +- src/test/ui/issues/issue-22706.stderr | 4 +- src/test/ui/mod-subitem-as-enum-variant.rs | 10 ++ .../ui/mod-subitem-as-enum-variant.stderr | 9 ++ src/test/ui/prim-with-args.rs | 44 +++--- src/test/ui/prim-with-args.stderr | 132 +++++++++--------- .../ui/qualified/qualified-path-params-2.rs | 2 +- .../qualified/qualified-path-params-2.stderr | 4 +- .../collections.rs | 12 +- .../collections.stderr | 20 +-- .../construct_with_other_type.rs | 8 +- .../construct_with_other_type.stderr | 12 +- ...ic_associated_type_undeclared_lifetimes.rs | 8 +- ...ssociated_type_undeclared_lifetimes.stderr | 12 +- .../iterable.rs | 14 +- .../iterable.stderr | 24 ++-- .../parameter_number_and_kind.rs | 12 +- .../parameter_number_and_kind.stderr | 20 +-- .../pointer_family.rs | 10 +- .../pointer_family.stderr | 16 +-- .../streaming_iterator.rs | 12 +- .../streaming_iterator.stderr | 20 +-- .../ui/structs/struct-path-associated-type.rs | 6 +- .../struct-path-associated-type.stderr | 14 +- src/test/ui/structs/struct-path-self.rs | 6 +- src/test/ui/structs/struct-path-self.stderr | 16 +-- src/test/ui/type-alias-enum-variants.rs | 2 +- src/test/ui/type-alias-enum-variants.stderr | 4 +- 35 files changed, 306 insertions(+), 279 deletions(-) create mode 100644 src/test/ui/mod-subitem-as-enum-variant.rs create mode 100644 src/test/ui/mod-subitem-as-enum-variant.stderr diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index f92ac4f74c3d7..f0fbf5b9e3e30 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -420,7 +420,7 @@ pub struct GenericArgs { /// The generic arguments for this path segment. pub args: HirVec, /// Bindings (equality constraints) on associated types, if present. - /// E.g., `Foo`. + /// E.g., `Foo`. pub bindings: HirVec, /// Were arguments written in parenthesized form `Fn(T) -> U`? /// This is required mostly for pretty-printing and diagnostics, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f15a27fbc8b59..2679f03377206 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1437,7 +1437,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { if err_for_lt { continue } err_for_lt = true; (struct_span_err!(self.tcx().sess, lt.span, E0110, - "lifetime parameters are not allowed on this type"), + "lifetime arguments are not allowed on this entity"), lt.span, "lifetime") } @@ -1445,12 +1445,12 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { if err_for_ty { continue } err_for_ty = true; (struct_span_err!(self.tcx().sess, ty.span, E0109, - "type parameters are not allowed on this type"), + "type arguments are not allowed on this entity"), ty.span, "type") } }; - span_err.span_label(span, format!("{} parameter not allowed", kind)) + span_err.span_label(span, format!("{} argument not allowed", kind)) .emit(); if err_for_lt && err_for_ty { break; diff --git a/src/librustc_typeck/diagnostics.rs b/src/librustc_typeck/diagnostics.rs index 425b428ecf2db..5910a8b3110d0 100644 --- a/src/librustc_typeck/diagnostics.rs +++ b/src/librustc_typeck/diagnostics.rs @@ -1291,7 +1291,7 @@ You tried to give a type parameter to a type which doesn't need it. Erroneous code example: ```compile_fail,E0109 -type X = u32; // error: type parameters are not allowed on this type +type X = u32; // error: type arguments are not allowed on this entity ``` Please check that you used the correct type and recheck its definition. Perhaps diff --git a/src/test/ui/enum-variant-generic-args.rs b/src/test/ui/enum-variant-generic-args.rs index 37109e89624b0..2ae4b756b7c05 100644 --- a/src/test/ui/enum-variant-generic-args.rs +++ b/src/test/ui/enum-variant-generic-args.rs @@ -7,22 +7,22 @@ type AliasFixed = Enum<()>; impl Enum { fn ts_variant() { Self::TSVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Self::<()>::TSVariant(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Self::<()>::TSVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - //~^^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] + //~^^ ERROR type arguments are not allowed on this entity [E0109] } fn s_variant() { Self::SVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Self::<()>::SVariant(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Self::<()>::SVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] - //~^^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] + //~^^ ERROR type arguments are not allowed on this entity [E0109] } } @@ -30,36 +30,36 @@ fn main() { // Tuple struct variant Enum::<()>::TSVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Alias::TSVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Alias::<()>::TSVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] AliasFixed::TSVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] AliasFixed::<()>::TSVariant(()); //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] AliasFixed::<()>::TSVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] // Struct variant Enum::<()>::SVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Alias::SVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Alias::<()>::SVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] AliasFixed::SVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] AliasFixed::<()>::SVariant(()); //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] AliasFixed::<()>::SVariant::<()>(()); - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] } diff --git a/src/test/ui/enum-variant-generic-args.stderr b/src/test/ui/enum-variant-generic-args.stderr index 4cae164b6ff46..2d622a49e20af 100644 --- a/src/test/ui/enum-variant-generic-args.stderr +++ b/src/test/ui/enum-variant-generic-args.stderr @@ -7,35 +7,35 @@ LL | Enum::<()>::SVariant::<()>(()); | | did you mean `TSVariant`? | did you mean `Enum::SVariant { /* fields */ }`? -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:9:27 | LL | Self::TSVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:11:16 | LL | Self::<()>::TSVariant(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:13:16 | LL | Self::<()>::TSVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:13:33 | LL | Self::<()>::TSVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:19:26 | LL | Self::SVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0618]: expected function, found enum variant `::SVariant::<()>` --> $DIR/enum-variant-generic-args.rs:19:9 @@ -52,11 +52,11 @@ help: `::SVariant::<()>` is a unit variant, you need to write it without t LL | ::SVariant::<()>; | ^^^^^^^^^^^^^^^^^^^^^^ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:21:16 | LL | Self::<()>::SVariant(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0618]: expected function, found enum variant `>::SVariant` --> $DIR/enum-variant-generic-args.rs:21:9 @@ -73,17 +73,17 @@ help: `>::SVariant` is a unit variant, you need to write it without the LL | >::SVariant; | ^^^^^^^^^^^^^^^^^^^^ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:23:16 | LL | Self::<()>::SVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:23:32 | LL | Self::<()>::SVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0618]: expected function, found enum variant `>::SVariant::<()>` --> $DIR/enum-variant-generic-args.rs:23:9 @@ -100,29 +100,29 @@ help: `>::SVariant::<()>` is a unit variant, you need to write it witho LL | >::SVariant::<()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:32:29 | LL | Enum::<()>::TSVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:35:24 | LL | Alias::TSVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:37:30 | LL | Alias::<()>::TSVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:40:29 | LL | AliasFixed::TSVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0107]: wrong number of type arguments: expected 0, found 1 --> $DIR/enum-variant-generic-args.rs:42:18 @@ -136,17 +136,17 @@ error[E0107]: wrong number of type arguments: expected 0, found 1 LL | AliasFixed::<()>::TSVariant::<()>(()); | ^^ unexpected type argument -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:44:35 | LL | AliasFixed::<()>::TSVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:53:23 | LL | Alias::SVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0618]: expected function, found enum variant `::SVariant::<()>` --> $DIR/enum-variant-generic-args.rs:53:5 @@ -163,11 +163,11 @@ help: `::SVariant::<()>` is a unit variant, you need to write it without LL | ::SVariant::<()>; | ^^^^^^^^^^^^^^^^^^^^^^^ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:55:29 | LL | Alias::<()>::SVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0618]: expected function, found enum variant `>::SVariant::<()>` --> $DIR/enum-variant-generic-args.rs:55:5 @@ -184,11 +184,11 @@ help: `>::SVariant::<()>` is a unit variant, you need to write it with LL | >::SVariant::<()>; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:58:28 | LL | AliasFixed::SVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0618]: expected function, found enum variant `::SVariant::<()>` --> $DIR/enum-variant-generic-args.rs:58:5 @@ -232,11 +232,11 @@ error[E0107]: wrong number of type arguments: expected 0, found 1 LL | AliasFixed::<()>::SVariant::<()>(()); | ^^ unexpected type argument -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:62:34 | LL | AliasFixed::<()>::SVariant::<()>(()); - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0618]: expected function, found enum variant `>::SVariant::<()>` --> $DIR/enum-variant-generic-args.rs:62:5 diff --git a/src/test/ui/error-codes/E0109.stderr b/src/test/ui/error-codes/E0109.stderr index 447b106c6296b..a5508f9808576 100644 --- a/src/test/ui/error-codes/E0109.stderr +++ b/src/test/ui/error-codes/E0109.stderr @@ -1,8 +1,8 @@ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/E0109.rs:1:14 | LL | type X = u32; //~ ERROR E0109 - | ^^^ type parameter not allowed + | ^^^ type argument not allowed error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0110.stderr b/src/test/ui/error-codes/E0110.stderr index 609b8b58276ff..be9b4229aeb60 100644 --- a/src/test/ui/error-codes/E0110.stderr +++ b/src/test/ui/error-codes/E0110.stderr @@ -1,8 +1,16 @@ -error[E0110]: lifetime parameters are not allowed on this type +<<<<<<< HEAD +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/E0110.rs:1:14 +||||||| merged common ancestors +error[E0110]: lifetime parameters are not allowed on this type + --> $DIR/E0110.rs:11:14 +======= +error[E0110]: lifetime arguments are not allowed on this entity + --> $DIR/E0110.rs:11:14 +>>>>>>> Added regression test for using generic parameters on modules. | LL | type X = u32<'static>; //~ ERROR E0110 - | ^^^^^^^ lifetime parameter not allowed + | ^^^^^^^ lifetime argument not allowed error: aborting due to previous error diff --git a/src/test/ui/issues/issue-22706.rs b/src/test/ui/issues/issue-22706.rs index c19c2a4c7059b..413a0d9a4943a 100644 --- a/src/test/ui/issues/issue-22706.rs +++ b/src/test/ui/issues/issue-22706.rs @@ -1,3 +1,3 @@ fn is_copy::Copy>() {} -//~^ ERROR type parameters are not allowed on this type [E0109] +//~^ ERROR type arguments are not allowed on this entity [E0109] fn main() {} diff --git a/src/test/ui/issues/issue-22706.stderr b/src/test/ui/issues/issue-22706.stderr index 57e62599b196f..a3cf716903d20 100644 --- a/src/test/ui/issues/issue-22706.stderr +++ b/src/test/ui/issues/issue-22706.stderr @@ -1,8 +1,8 @@ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/issue-22706.rs:1:29 | LL | fn is_copy::Copy>() {} - | ^^^ type parameter not allowed + | ^^^ type argument not allowed error: aborting due to previous error diff --git a/src/test/ui/mod-subitem-as-enum-variant.rs b/src/test/ui/mod-subitem-as-enum-variant.rs new file mode 100644 index 0000000000000..ec809d44e942a --- /dev/null +++ b/src/test/ui/mod-subitem-as-enum-variant.rs @@ -0,0 +1,10 @@ + +mod Mod { + pub struct FakeVariant(pub T); +} + +fn main() { + Mod::FakeVariant::(0); + Mod::::FakeVariant(0); + //~^ ERROR type arguments are not allowed on this entity [E0109] +} diff --git a/src/test/ui/mod-subitem-as-enum-variant.stderr b/src/test/ui/mod-subitem-as-enum-variant.stderr new file mode 100644 index 0000000000000..d62bad81c3d8d --- /dev/null +++ b/src/test/ui/mod-subitem-as-enum-variant.stderr @@ -0,0 +1,9 @@ +error[E0109]: type arguments are not allowed on this entity + --> $DIR/mod-subitem-as-enum-variant.rs:8:11 + | +LL | Mod::::FakeVariant(0); + | ^^^ type argument not allowed + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0109`. diff --git a/src/test/ui/prim-with-args.rs b/src/test/ui/prim-with-args.rs index 52443a729e5bc..b5df0fb76ca6a 100644 --- a/src/test/ui/prim-with-args.rs +++ b/src/test/ui/prim-with-args.rs @@ -1,27 +1,27 @@ fn main() { -let x: isize; //~ ERROR type parameters are not allowed on this type -let x: i8; //~ ERROR type parameters are not allowed on this type -let x: i16; //~ ERROR type parameters are not allowed on this type -let x: i32; //~ ERROR type parameters are not allowed on this type -let x: i64; //~ ERROR type parameters are not allowed on this type -let x: usize; //~ ERROR type parameters are not allowed on this type -let x: u8; //~ ERROR type parameters are not allowed on this type -let x: u16; //~ ERROR type parameters are not allowed on this type -let x: u32; //~ ERROR type parameters are not allowed on this type -let x: u64; //~ ERROR type parameters are not allowed on this type -let x: char; //~ ERROR type parameters are not allowed on this type +let x: isize; //~ ERROR type arguments are not allowed on this entity +let x: i8; //~ ERROR type arguments are not allowed on this entity +let x: i16; //~ ERROR type arguments are not allowed on this entity +let x: i32; //~ ERROR type arguments are not allowed on this entity +let x: i64; //~ ERROR type arguments are not allowed on this entity +let x: usize; //~ ERROR type arguments are not allowed on this entity +let x: u8; //~ ERROR type arguments are not allowed on this entity +let x: u16; //~ ERROR type arguments are not allowed on this entity +let x: u32; //~ ERROR type arguments are not allowed on this entity +let x: u64; //~ ERROR type arguments are not allowed on this entity +let x: char; //~ ERROR type arguments are not allowed on this entity -let x: isize<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: i8<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: i16<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: i32<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: i64<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: usize<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: u8<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: u16<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: u32<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: u64<'static>; //~ ERROR lifetime parameters are not allowed on this type -let x: char<'static>; //~ ERROR lifetime parameters are not allowed on this type +let x: isize<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: i8<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: i16<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: i32<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: i64<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: usize<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: u8<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: u16<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: u32<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: u64<'static>; //~ ERROR lifetime arguments are not allowed on this entity +let x: char<'static>; //~ ERROR lifetime arguments are not allowed on this entity } diff --git a/src/test/ui/prim-with-args.stderr b/src/test/ui/prim-with-args.stderr index 190c45a1624d1..91259e87efc02 100644 --- a/src/test/ui/prim-with-args.stderr +++ b/src/test/ui/prim-with-args.stderr @@ -1,134 +1,134 @@ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:3:14 | -LL | let x: isize; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: isize; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:4:11 | -LL | let x: i8; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: i8; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:5:12 | -LL | let x: i16; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: i16; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:6:12 | -LL | let x: i32; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: i32; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:7:12 | -LL | let x: i64; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: i64; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:8:14 | -LL | let x: usize; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: usize; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:9:11 | -LL | let x: u8; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: u8; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:10:12 | -LL | let x: u16; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: u16; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:11:12 | -LL | let x: u32; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: u32; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:12:12 | -LL | let x: u64; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: u64; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/prim-with-args.rs:13:13 | -LL | let x: char; //~ ERROR type parameters are not allowed on this type - | ^^^^^ type parameter not allowed +LL | let x: char; //~ ERROR type arguments are not allowed on this entity + | ^^^^^ type argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:15:14 | -LL | let x: isize<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: isize<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:16:11 | -LL | let x: i8<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: i8<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:17:12 | -LL | let x: i16<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: i16<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:18:12 | -LL | let x: i32<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: i32<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:19:12 | -LL | let x: i64<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: i64<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:20:14 | -LL | let x: usize<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: usize<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:21:11 | -LL | let x: u8<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: u8<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:22:12 | -LL | let x: u16<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: u16<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:23:12 | -LL | let x: u32<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: u32<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:24:12 | -LL | let x: u64<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: u64<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/prim-with-args.rs:25:13 | -LL | let x: char<'static>; //~ ERROR lifetime parameters are not allowed on this type - | ^^^^^^^ lifetime parameter not allowed +LL | let x: char<'static>; //~ ERROR lifetime arguments are not allowed on this entity + | ^^^^^^^ lifetime argument not allowed error: aborting due to 22 previous errors diff --git a/src/test/ui/qualified/qualified-path-params-2.rs b/src/test/ui/qualified/qualified-path-params-2.rs index 6ee55f54bdbb5..8412983fda549 100644 --- a/src/test/ui/qualified/qualified-path-params-2.rs +++ b/src/test/ui/qualified/qualified-path-params-2.rs @@ -16,7 +16,7 @@ impl S { } type A = ::A::f; -//~^ ERROR type parameters are not allowed on this type +//~^ ERROR type arguments are not allowed on this entity //~| ERROR ambiguous associated type fn main() {} diff --git a/src/test/ui/qualified/qualified-path-params-2.stderr b/src/test/ui/qualified/qualified-path-params-2.stderr index 91c3d704cb9dd..4e073841b9740 100644 --- a/src/test/ui/qualified/qualified-path-params-2.stderr +++ b/src/test/ui/qualified/qualified-path-params-2.stderr @@ -1,8 +1,8 @@ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/qualified-path-params-2.rs:18:26 | LL | type A = ::A::f; - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0223]: ambiguous associated type --> $DIR/qualified-path-params-2.rs:18:10 diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.rs b/src/test/ui/rfc1598-generic-associated-types/collections.rs index e1a65c28803e2..5414bb4a6d20e 100644 --- a/src/test/ui/rfc1598-generic-associated-types/collections.rs +++ b/src/test/ui/rfc1598-generic-associated-types/collections.rs @@ -2,7 +2,7 @@ //~^ WARNING the feature `generic_associated_types` is incomplete #![feature(associated_type_defaults)] -// FIXME(#44265): "lifetime parameters are not allowed on this type" errors will be addressed in a +// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a // follow-up PR. // A Collection trait and collection families. Based on @@ -15,14 +15,14 @@ trait Collection { // Test associated type defaults with parameters type Sibling: Collection = <>::Family as CollectionFamily>::Member; - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] fn empty() -> Self; fn add(&mut self, value: T); fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] } trait CollectionFamily { @@ -48,13 +48,13 @@ impl Collection for Vec { } fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] self.iter() } } fn floatify(ints: &C) -> <>::Family as CollectionFamily>::Member -//~^ ERROR type parameters are not allowed on this type [E0109] +//~^ ERROR type arguments are not allowed on this entity [E0109] where C: Collection, { @@ -66,7 +66,7 @@ where } fn floatify_sibling(ints: &C) -> >::Sibling -//~^ ERROR type parameters are not allowed on this type [E0109] +//~^ ERROR type arguments are not allowed on this entity [E0109] where C: Collection, { diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.stderr b/src/test/ui/rfc1598-generic-associated-types/collections.stderr index e90a6b8ad138c..b3fb81b418e8c 100644 --- a/src/test/ui/rfc1598-generic-associated-types/collections.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/collections.stderr @@ -4,35 +4,35 @@ warning: the feature `generic_associated_types` is incomplete and may cause the LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/collections.rs:56:90 | LL | fn floatify(ints: &C) -> <>::Family as CollectionFamily>::Member - | ^^^ type parameter not allowed + | ^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/collections.rs:68:69 | LL | fn floatify_sibling(ints: &C) -> >::Sibling - | ^^^ type parameter not allowed + | ^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/collections.rs:17:71 | LL | <>::Family as CollectionFamily>::Member; - | ^ type parameter not allowed + | ^ type argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/collections.rs:24:50 | LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; - | ^^^^^ lifetime parameter not allowed + | ^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/collections.rs:50:50 | LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> { - | ^^^^^ lifetime parameter not allowed + | ^^^^^ lifetime argument not allowed error: aborting due to 5 previous errors diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs index 85935d1cca6bf..d9c482e23e47c 100644 --- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs +++ b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.rs @@ -3,7 +3,7 @@ use std::ops::Deref; -// FIXME(#44265): "lifetime parameters are not allowed on this type" errors will be addressed in a +// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a // follow-up PR. trait Foo { @@ -15,15 +15,15 @@ trait Baz { // This weird type tests that we can use universal function call syntax to access the Item on type Baa<'a>: Deref as Foo>::Bar<'a, 'static>>; - //~^ ERROR lifetime parameters are not allowed on this type [E0110] - //~| ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] + //~| ERROR lifetime arguments are not allowed on this entity [E0110] } impl Baz for T where T: Foo { type Quux<'a> = T; type Baa<'a> = &'a ::Bar<'a, 'static>; - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] } fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr index 100809f62a55c..fd6116d2da23a 100644 --- a/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/construct_with_other_type.stderr @@ -4,23 +4,23 @@ warning: the feature `generic_associated_types` is incomplete and may cause the LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/construct_with_other_type.rs:17:46 | LL | type Baa<'a>: Deref as Foo>::Bar<'a, 'static>>; - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/construct_with_other_type.rs:17:63 | LL | type Baa<'a>: Deref as Foo>::Bar<'a, 'static>>; - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/construct_with_other_type.rs:25:40 | LL | type Baa<'a> = &'a ::Bar<'a, 'static>; - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed error: aborting due to 3 previous errors diff --git a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs index bfdd12003885a..2e6d7470b49a2 100644 --- a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs +++ b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.rs @@ -3,20 +3,20 @@ use std::ops::Deref; -// FIXME(#44265): "lifetime parameters are not allowed on this type" errors will be addressed in a +// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a // follow-up PR. trait Iterable { type Item<'a>; type Iter<'a>: Iterator> - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] + Deref>; //~^ ERROR undeclared lifetime - //~| ERROR lifetime parameters are not allowed on this type [E0110] + //~| ERROR lifetime arguments are not allowed on this entity [E0110] fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; //~^ ERROR undeclared lifetime - //~| ERROR lifetime parameters are not allowed on this type [E0110] + //~| ERROR lifetime arguments are not allowed on this entity [E0110] } fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr index f5b42866dc6b4..3cebab6389557 100644 --- a/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/generic_associated_type_undeclared_lifetimes.stderr @@ -16,23 +16,23 @@ error[E0261]: use of undeclared lifetime name `'undeclared` LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; | ^^^^^^^^^^^ undeclared lifetime -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/generic_associated_type_undeclared_lifetimes.rs:11:47 | LL | type Iter<'a>: Iterator> - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/generic_associated_type_undeclared_lifetimes.rs:13:37 | LL | + Deref>; - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/generic_associated_type_undeclared_lifetimes.rs:17:41 | LL | fn iter<'a>(&'a self) -> Self::Iter<'undeclared>; - | ^^^^^^^^^^^ lifetime parameter not allowed + | ^^^^^^^^^^^ lifetime argument not allowed error: aborting due to 5 previous errors diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.rs b/src/test/ui/rfc1598-generic-associated-types/iterable.rs index 16ed4a7546cc3..69258506651c4 100644 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.rs +++ b/src/test/ui/rfc1598-generic-associated-types/iterable.rs @@ -3,16 +3,16 @@ use std::ops::Deref; -// FIXME(#44265): "lifetime parameters are not allowed on this type" errors will be addressed in a +// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a // follow-up PR. trait Iterable { type Item<'a>; type Iter<'a>: Iterator>; - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] fn iter<'a>(&'a self) -> Self::Iter<'a>; - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] } // Impl for struct type @@ -21,7 +21,7 @@ impl Iterable for Vec { type Iter<'a> = std::slice::Iter<'a, T>; fn iter<'a>(&'a self) -> Self::Iter<'a> { - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] self.iter() } } @@ -32,18 +32,18 @@ impl Iterable for [T] { type Iter<'a> = std::slice::Iter<'a, T>; fn iter<'a>(&'a self) -> Self::Iter<'a> { - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] self.iter() } } fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> { - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] it.iter() } fn get_first<'a, I: Iterable>(it: &'a I) -> Option> { - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] it.iter().next() } diff --git a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr index 41943d7d325e9..cc3ade6f39d90 100644 --- a/src/test/ui/rfc1598-generic-associated-types/iterable.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/iterable.stderr @@ -4,41 +4,41 @@ warning: the feature `generic_associated_types` is incomplete and may cause the LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/iterable.rs:11:47 | LL | type Iter<'a>: Iterator>; - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/iterable.rs:40:53 | LL | fn make_iter<'a, I: Iterable>(it: &'a I) -> I::Iter<'a> { - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/iterable.rs:45:60 | LL | fn get_first<'a, I: Iterable>(it: &'a I) -> Option> { - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/iterable.rs:14:41 | LL | fn iter<'a>(&'a self) -> Self::Iter<'a>; - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/iterable.rs:23:41 | LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/iterable.rs:34:41 | LL | fn iter<'a>(&'a self) -> Self::Iter<'a> { - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed error: aborting due to 6 previous errors diff --git a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs index 098d52b20faae..851e331a0e965 100644 --- a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs +++ b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.rs @@ -2,7 +2,7 @@ //~^ WARNING the feature `generic_associated_types` is incomplete #![feature(associated_type_defaults)] -// FIXME(#44265): "lifetime parameters are not allowed on this type" errors will be addressed in a +// FIXME(#44265): "lifetime arguments are not allowed on this entity" errors will be addressed in a // follow-up PR. // FIXME(#44265): Update expected errors once E110 is resolved, now does not get past `trait Foo`. @@ -15,13 +15,13 @@ trait Foo { type E<'a, T>; // Test parameters in default values type FOk = Self::E<'static, T>; - //~^ ERROR type parameters are not allowed on this type [E0109] - //~| ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR type arguments are not allowed on this entity [E0109] + //~| ERROR lifetime arguments are not allowed on this entity [E0110] type FErr1 = Self::E<'static, 'static>; // Error - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] type FErr2 = Self::E<'static, T, u32>; // Error - //~^ ERROR type parameters are not allowed on this type [E0109] - //~| ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR type arguments are not allowed on this entity [E0109] + //~| ERROR lifetime arguments are not allowed on this entity [E0110] } struct Fooy; diff --git a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr index dfd1648e5c0d6..265b0fab77061 100644 --- a/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/parameter_number_and_kind.stderr @@ -4,35 +4,35 @@ warning: the feature `generic_associated_types` is incomplete and may cause the LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/parameter_number_and_kind.rs:17:27 | LL | type FOk = Self::E<'static, T>; - | ^^^^^^^ lifetime parameter not allowed + | ^^^^^^^ lifetime argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/parameter_number_and_kind.rs:17:36 | LL | type FOk = Self::E<'static, T>; - | ^ type parameter not allowed + | ^ type argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/parameter_number_and_kind.rs:20:26 | LL | type FErr1 = Self::E<'static, 'static>; // Error - | ^^^^^^^ lifetime parameter not allowed + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/parameter_number_and_kind.rs:22:29 | LL | type FErr2 = Self::E<'static, T, u32>; // Error - | ^^^^^^^ lifetime parameter not allowed + | ^^^^^^^ lifetime argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/parameter_number_and_kind.rs:22:38 | LL | type FErr2 = Self::E<'static, T, u32>; // Error - | ^ type parameter not allowed + | ^ type argument not allowed error: aborting due to 5 previous errors diff --git a/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs b/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs index e11670ce1b316..2d188aed42778 100644 --- a/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs +++ b/src/test/ui/rfc1598-generic-associated-types/pointer_family.rs @@ -1,7 +1,7 @@ #![feature(generic_associated_types)] //~^ WARNING the feature `generic_associated_types` is incomplete -// FIXME(#44265): "type parameter not allowed" errors will be addressed in a follow-up PR. +// FIXME(#44265): "type argument not allowed" errors will be addressed in a follow-up PR. use std::rc::Rc; use std::sync::Arc; @@ -10,7 +10,7 @@ use std::ops::Deref; trait PointerFamily { type Pointer: Deref; fn new(value: T) -> Self::Pointer; - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] } struct ArcFamily; @@ -18,7 +18,7 @@ struct ArcFamily; impl PointerFamily for ArcFamily { type Pointer = Arc; fn new(value: T) -> Self::Pointer { - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Arc::new(value) } } @@ -28,14 +28,14 @@ struct RcFamily; impl PointerFamily for RcFamily { type Pointer = Rc; fn new(value: T) -> Self::Pointer { - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] Rc::new(value) } } struct Foo { bar: P::Pointer, - //~^ ERROR type parameters are not allowed on this type [E0109] + //~^ ERROR type arguments are not allowed on this entity [E0109] } fn main() {} diff --git a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr b/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr index 29c442a79e628..2b9eed2a688a2 100644 --- a/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/pointer_family.stderr @@ -4,29 +4,29 @@ warning: the feature `generic_associated_types` is incomplete and may cause the LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/pointer_family.rs:37:21 | LL | bar: P::Pointer, - | ^^^^^^ type parameter not allowed + | ^^^^^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/pointer_family.rs:12:42 | LL | fn new(value: T) -> Self::Pointer; - | ^ type parameter not allowed + | ^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/pointer_family.rs:20:42 | LL | fn new(value: T) -> Self::Pointer { - | ^ type parameter not allowed + | ^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/pointer_family.rs:30:42 | LL | fn new(value: T) -> Self::Pointer { - | ^ type parameter not allowed + | ^ type argument not allowed error: aborting due to 4 previous errors diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs index cb6e576804937..1ef154447903b 100644 --- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs +++ b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.rs @@ -1,7 +1,7 @@ #![feature(generic_associated_types)] //~^ WARNING the feature `generic_associated_types` is incomplete -// FIXME(#44265): "lifetime parameter not allowed on this type" errors will be addressed in a +// FIXME(#44265): "lifetime argument not allowed on this type" errors will be addressed in a // follow-up PR use std::fmt::Display; @@ -10,13 +10,13 @@ trait StreamingIterator { type Item<'a>; // Applying the lifetime parameter `'a` to `Self::Item` inside the trait. fn next<'a>(&'a self) -> Option>; - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] } struct Foo { // Applying a concrete lifetime to the constructor outside the trait. bar: ::Item<'static>, - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] } // Users can bound parameters by the type constructed by that trait's associated type constructor @@ -24,7 +24,7 @@ struct Foo { //FIXME(sunjay): This next line should parse and be valid //fn foo StreamingIterator=&'a [i32]>>(iter: T) { /* ... */ } fn foo(iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ } -//~^ ERROR lifetime parameters are not allowed on this type [E0110] +//~^ ERROR lifetime arguments are not allowed on this entity [E0110] // Full example of enumerate iterator @@ -36,9 +36,9 @@ struct StreamEnumerate { impl StreamingIterator for StreamEnumerate { type Item<'a> = (usize, I::Item<'a>); - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] fn next<'a>(&'a self) -> Option> { - //~^ ERROR lifetime parameters are not allowed on this type [E0110] + //~^ ERROR lifetime arguments are not allowed on this entity [E0110] match self.iter.next() { None => None, Some(val) => { diff --git a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr index af5d1b872cc6e..5afbba5d2d744 100644 --- a/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/streaming_iterator.stderr @@ -4,35 +4,35 @@ warning: the feature `generic_associated_types` is incomplete and may cause the LL | #![feature(generic_associated_types)] | ^^^^^^^^^^^^^^^^^^^^^^^^ -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/streaming_iterator.rs:18:41 | LL | bar: ::Item<'static>, - | ^^^^^^^ lifetime parameter not allowed + | ^^^^^^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/streaming_iterator.rs:26:64 | LL | fn foo(iter: T) where T: StreamingIterator, for<'a> T::Item<'a>: Display { /* ... */ } - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/streaming_iterator.rs:12:48 | LL | fn next<'a>(&'a self) -> Option>; - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/streaming_iterator.rs:38:37 | LL | type Item<'a> = (usize, I::Item<'a>); - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed -error[E0110]: lifetime parameters are not allowed on this type +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/streaming_iterator.rs:40:48 | LL | fn next<'a>(&'a self) -> Option> { - | ^^ lifetime parameter not allowed + | ^^ lifetime argument not allowed error: aborting due to 5 previous errors diff --git a/src/test/ui/structs/struct-path-associated-type.rs b/src/test/ui/structs/struct-path-associated-type.rs index 1cafe265b2e0e..7c770852d22d2 100644 --- a/src/test/ui/structs/struct-path-associated-type.rs +++ b/src/test/ui/structs/struct-path-associated-type.rs @@ -13,7 +13,7 @@ fn f() { //~^ ERROR expected struct, variant or union type, found associated type let z = T::A:: {}; //~^ ERROR expected struct, variant or union type, found associated type - //~| ERROR type parameters are not allowed on this type + //~| ERROR type arguments are not allowed on this entity match S { T::A {} => {} //~^ ERROR expected struct, variant or union type, found associated type @@ -22,7 +22,7 @@ fn f() { fn g>() { let s = T::A {}; // OK - let z = T::A:: {}; //~ ERROR type parameters are not allowed on this type + let z = T::A:: {}; //~ ERROR type arguments are not allowed on this entity match S { T::A {} => {} // OK } @@ -31,7 +31,7 @@ fn g>() { fn main() { let s = S::A {}; //~ ERROR ambiguous associated type let z = S::A:: {}; //~ ERROR ambiguous associated type - //~^ ERROR type parameters are not allowed on this type + //~^ ERROR type arguments are not allowed on this entity match S { S::A {} => {} //~ ERROR ambiguous associated type } diff --git a/src/test/ui/structs/struct-path-associated-type.stderr b/src/test/ui/structs/struct-path-associated-type.stderr index 41360d87930d1..80824d9847838 100644 --- a/src/test/ui/structs/struct-path-associated-type.stderr +++ b/src/test/ui/structs/struct-path-associated-type.stderr @@ -4,11 +4,11 @@ error[E0071]: expected struct, variant or union type, found associated type LL | let s = T::A {}; | ^^^^ not a struct -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/struct-path-associated-type.rs:14:20 | LL | let z = T::A:: {}; - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0071]: expected struct, variant or union type, found associated type --> $DIR/struct-path-associated-type.rs:14:13 @@ -22,11 +22,11 @@ error[E0071]: expected struct, variant or union type, found associated type LL | T::A {} => {} | ^^^^ not a struct -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/struct-path-associated-type.rs:25:20 | -LL | let z = T::A:: {}; //~ ERROR type parameters are not allowed on this type - | ^^ type parameter not allowed +LL | let z = T::A:: {}; //~ ERROR type arguments are not allowed on this entity + | ^^ type argument not allowed error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:32:13 @@ -34,11 +34,11 @@ error[E0223]: ambiguous associated type LL | let s = S::A {}; //~ ERROR ambiguous associated type | ^^^^ help: use fully-qualified syntax: `::A` -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/struct-path-associated-type.rs:33:20 | LL | let z = S::A:: {}; //~ ERROR ambiguous associated type - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0223]: ambiguous associated type --> $DIR/struct-path-associated-type.rs:33:13 diff --git a/src/test/ui/structs/struct-path-self.rs b/src/test/ui/structs/struct-path-self.rs index ccbf3db29b1d9..51ed9e5457eb7 100644 --- a/src/test/ui/structs/struct-path-self.rs +++ b/src/test/ui/structs/struct-path-self.rs @@ -6,7 +6,7 @@ trait Tr { //~^ ERROR expected struct, variant or union type, found Self let z = Self:: {}; //~^ ERROR expected struct, variant or union type, found Self - //~| ERROR type parameters are not allowed on this type + //~| ERROR type arguments are not allowed on this entity match s { Self { .. } => {} //~^ ERROR expected struct, variant or union type, found Self @@ -17,7 +17,7 @@ trait Tr { impl Tr for S { fn f() { let s = Self {}; // OK - let z = Self:: {}; //~ ERROR type parameters are not allowed on this type + let z = Self:: {}; //~ ERROR type arguments are not allowed on this entity match s { Self { .. } => {} // OK } @@ -27,7 +27,7 @@ impl Tr for S { impl S { fn g() { let s = Self {}; // OK - let z = Self:: {}; //~ ERROR type parameters are not allowed on this type + let z = Self:: {}; //~ ERROR type arguments are not allowed on this entity match s { Self { .. } => {} // OK } diff --git a/src/test/ui/structs/struct-path-self.stderr b/src/test/ui/structs/struct-path-self.stderr index a1df1a0764ccb..cda6b7a533f65 100644 --- a/src/test/ui/structs/struct-path-self.stderr +++ b/src/test/ui/structs/struct-path-self.stderr @@ -4,11 +4,11 @@ error[E0071]: expected struct, variant or union type, found Self LL | let s = Self {}; | ^^^^ not a struct -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/struct-path-self.rs:7:24 | LL | let z = Self:: {}; - | ^^ type parameter not allowed + | ^^ type argument not allowed error[E0071]: expected struct, variant or union type, found Self --> $DIR/struct-path-self.rs:7:17 @@ -22,17 +22,17 @@ error[E0071]: expected struct, variant or union type, found Self LL | Self { .. } => {} | ^^^^ not a struct -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/struct-path-self.rs:20:24 | -LL | let z = Self:: {}; //~ ERROR type parameters are not allowed on this type - | ^^ type parameter not allowed +LL | let z = Self:: {}; //~ ERROR type arguments are not allowed on this entity + | ^^ type argument not allowed -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/struct-path-self.rs:30:24 | -LL | let z = Self:: {}; //~ ERROR type parameters are not allowed on this type - | ^^ type parameter not allowed +LL | let z = Self:: {}; //~ ERROR type arguments are not allowed on this entity + | ^^ type argument not allowed error: aborting due to 6 previous errors diff --git a/src/test/ui/type-alias-enum-variants.rs b/src/test/ui/type-alias-enum-variants.rs index 73395e6a9798a..3ec200d57c55d 100644 --- a/src/test/ui/type-alias-enum-variants.rs +++ b/src/test/ui/type-alias-enum-variants.rs @@ -7,5 +7,5 @@ fn main() { let _ = Option::None::; // OK (Lint in future!) let _ = Alias::::None; // OK let _ = Alias::None::; // Error - //~^ type parameters are not allowed on this type + //~^ type arguments are not allowed on this entity } diff --git a/src/test/ui/type-alias-enum-variants.stderr b/src/test/ui/type-alias-enum-variants.stderr index e7003217c8d7c..cf81f5b27ac6b 100644 --- a/src/test/ui/type-alias-enum-variants.stderr +++ b/src/test/ui/type-alias-enum-variants.stderr @@ -1,8 +1,8 @@ -error[E0109]: type parameters are not allowed on this type +error[E0109]: type arguments are not allowed on this entity --> $DIR/type-alias-enum-variants.rs:9:27 | LL | let _ = Alias::None::; // Error - | ^^ type parameter not allowed + | ^^ type argument not allowed error: aborting due to previous error From fa07e6238985a329d82ee09de7587f7f90c7a4d2 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Tue, 18 Dec 2018 18:59:00 +0000 Subject: [PATCH 16/22] Fixed handling of unit variants of aliased enums in type NS. --- src/librustc_typeck/astconv.rs | 152 +++++++++++++- src/librustc_typeck/check/mod.rs | 132 +----------- .../run-pass/enum-variant-generic-args.rs | 6 +- src/test/ui/enum-variant-generic-args.rs | 21 +- src/test/ui/enum-variant-generic-args.stderr | 198 +++++------------- 5 files changed, 215 insertions(+), 294 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 2679f03377206..98013dd00dc70 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -32,6 +32,10 @@ use std::iter; use std::slice; use super::{check_type_alias_enum_variants_enabled}; +use rustc_data_structures::fx::FxHashSet; + +#[derive(Debug)] +pub struct PathSeg(pub DefId, pub usize); pub trait AstConv<'gcx, 'tcx> { fn tcx<'a>(&'a self) -> TyCtxt<'a, 'gcx, 'tcx>; @@ -1470,6 +1474,134 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { err.span_label(span, "associated type not allowed here").emit(); } + pub fn def_ids_for_path_segments(&self, + segments: &[hir::PathSegment], + self_ty: Option>, + def: Def) + -> Vec { + // We need to extract the type parameters supplied by the user in + // the path `path`. Due to the current setup, this is a bit of a + // tricky-process; the problem is that resolve only tells us the + // end-point of the path resolution, and not the intermediate steps. + // Luckily, we can (at least for now) deduce the intermediate steps + // just from the end-point. + // + // There are basically five cases to consider: + // + // 1. Reference to a constructor of a struct: + // + // struct Foo(...) + // + // In this case, the parameters are declared in the type space. + // + // 2. Reference to a constructor of an enum variant: + // + // enum E { Foo(...) } + // + // In this case, the parameters are defined in the type space, + // but may be specified either on the type or the variant. + // + // 3. Reference to a fn item or a free constant: + // + // fn foo() { } + // + // In this case, the path will again always have the form + // `a::b::foo::` where only the final segment should have + // type parameters. However, in this case, those parameters are + // declared on a value, and hence are in the `FnSpace`. + // + // 4. Reference to a method or an associated constant: + // + // impl SomeStruct { + // fn foo(...) + // } + // + // Here we can have a path like + // `a::b::SomeStruct::::foo::`, in which case parameters + // may appear in two places. The penultimate segment, + // `SomeStruct::`, contains parameters in TypeSpace, and the + // final segment, `foo::` contains parameters in fn space. + // + // 5. Reference to a local variable + // + // Local variables can't have any type parameters. + // + // The first step then is to categorize the segments appropriately. + + let tcx = self.tcx(); + + assert!(!segments.is_empty()); + let last = segments.len() - 1; + + let mut path_segs = vec![]; + + match def { + // Case 1. Reference to a struct constructor. + Def::StructCtor(def_id, ..) | + Def::SelfCtor(.., def_id) => { + // Everything but the final segment should have no + // parameters at all. + let generics = tcx.generics_of(def_id); + // Variant and struct constructors use the + // generics of their parent type definition. + let generics_def_id = generics.parent.unwrap_or(def_id); + path_segs.push(PathSeg(generics_def_id, last)); + } + + // Case 2. Reference to a variant constructor. + Def::Variant(def_id) | + Def::VariantCtor(def_id, ..) => { + let adt_def = self_ty.and_then(|t| t.ty_adt_def()); + let (generics_def_id, index) = if let Some(adt_def) = adt_def { + debug_assert!(adt_def.is_enum()); + (adt_def.did, last) + } else if last >= 1 && segments[last - 1].args.is_some() { + // Everything but the penultimate segment should have no + // parameters at all. + let enum_def_id = tcx.parent_def_id(def_id).unwrap(); + (enum_def_id, last - 1) + } else { + // FIXME: lint here recommending `Enum::<...>::Variant` form + // instead of `Enum::Variant::<...>` form. + + // Everything but the final segment should have no + // parameters at all. + let generics = tcx.generics_of(def_id); + // Variant and struct constructors use the + // generics of their parent type definition. + (generics.parent.unwrap_or(def_id), last) + }; + path_segs.push(PathSeg(generics_def_id, index)); + } + + // Case 3. Reference to a top-level value. + Def::Fn(def_id) | + Def::Const(def_id) | + Def::Static(def_id, _) => { + path_segs.push(PathSeg(def_id, last)); + } + + // Case 4. Reference to a method or associated const. + Def::Method(def_id) | + Def::AssociatedConst(def_id) => { + if segments.len() >= 2 { + let generics = tcx.generics_of(def_id); + path_segs.push(PathSeg(generics.parent.unwrap(), last - 1)); + } + path_segs.push(PathSeg(def_id, last)); + } + + // Case 5. Local variable, no generics. + Def::Local(..) | Def::Upvar(..) => {} + + _ => bug!("unexpected definition: {:?}", def), + } + + debug!("path_segs = {:?}", path_segs); + + path_segs + } + // Check a type `Path` and convert it to a `Ty`. pub fn def_to_ty(&self, opt_self_ty: Option>, @@ -1500,14 +1632,24 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { self.prohibit_generics(path.segments.split_last().unwrap().1); self.ast_path_to_ty(span, did, path.segments.last().unwrap()) } - Def::Variant(did) if permit_variants => { + Def::Variant(_) if permit_variants => { // Convert "variant type" as if it were a real type. // The resulting `Ty` is type of the variant's enum for now. assert_eq!(opt_self_ty, None); - self.prohibit_generics(path.segments.split_last().unwrap().1); - self.ast_path_to_ty(span, - tcx.parent_def_id(did).unwrap(), - path.segments.last().unwrap()) + + let path_segs = self.def_ids_for_path_segments(&path.segments, None, path.def); + let generic_segs: FxHashSet<_> = + path_segs.iter().map(|PathSeg(_, index)| index).collect(); + self.prohibit_generics(path.segments.iter().enumerate().filter_map(|(index, seg)| { + if !generic_segs.contains(&index) { + Some(seg) + } else { + None + } + })); + + let PathSeg(def_id, index) = path_segs.last().unwrap(); + self.ast_path_to_ty(span, *def_id, &path.segments[*index]) } Def::TyParam(did) => { assert_eq!(opt_self_ty, None); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index bf878f87e3693..76fbe862211cf 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -83,7 +83,7 @@ mod generator_interior; mod intrinsic; mod op; -use astconv::AstConv; +use astconv::{AstConv, PathSeg}; use errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use rustc::hir::{self, ExprKind, GenericArg, ItemKind, Node, PatKind, QPath}; use rustc::hir::def::{CtorKind, Def}; @@ -507,9 +507,6 @@ impl<'gcx, 'tcx> EnclosingBreakables<'gcx, 'tcx> { } } -#[derive(Debug)] -struct PathSeg(DefId, usize); - pub struct FnCtxt<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { body_id: ast::NodeId, @@ -5060,131 +5057,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Applicability::MachineApplicable); } - fn def_ids_for_path_segments(&self, - segments: &[hir::PathSegment], - self_ty: Option>, - def: Def) - -> Vec { - // We need to extract the type parameters supplied by the user in - // the path `path`. Due to the current setup, this is a bit of a - // tricky-process; the problem is that resolve only tells us the - // end-point of the path resolution, and not the intermediate steps. - // Luckily, we can (at least for now) deduce the intermediate steps - // just from the end-point. - // - // There are basically five cases to consider: - // - // 1. Reference to a constructor of a struct: - // - // struct Foo(...) - // - // In this case, the parameters are declared in the type space. - // - // 2. Reference to a constructor of an enum variant: - // - // enum E { Foo(...) } - // - // In this case, the parameters are defined in the type space, - // but may be specified either on the type or the variant. - // - // 3. Reference to a fn item or a free constant: - // - // fn foo() { } - // - // In this case, the path will again always have the form - // `a::b::foo::` where only the final segment should have - // type parameters. However, in this case, those parameters are - // declared on a value, and hence are in the `FnSpace`. - // - // 4. Reference to a method or an associated constant: - // - // impl SomeStruct { - // fn foo(...) - // } - // - // Here we can have a path like - // `a::b::SomeStruct::::foo::`, in which case parameters - // may appear in two places. The penultimate segment, - // `SomeStruct::`, contains parameters in TypeSpace, and the - // final segment, `foo::` contains parameters in fn space. - // - // 5. Reference to a local variable - // - // Local variables can't have any type parameters. - // - // The first step then is to categorize the segments appropriately. - - assert!(!segments.is_empty()); - let last = segments.len() - 1; - - let mut path_segs = vec![]; - - match def { - // Case 1. Reference to a struct constructor. - Def::StructCtor(def_id, ..) | - Def::SelfCtor(.., def_id) => { - // Everything but the final segment should have no - // parameters at all. - let generics = self.tcx.generics_of(def_id); - // Variant and struct constructors use the - // generics of their parent type definition. - let generics_def_id = generics.parent.unwrap_or(def_id); - path_segs.push(PathSeg(generics_def_id, last)); - } - - // Case 2. Reference to a variant constructor. - Def::VariantCtor(def_id, ..) => { - let adt_def = self_ty.and_then(|t| t.ty_adt_def()); - let (generics_def_id, index) = if let Some(adt_def) = adt_def { - debug_assert!(adt_def.is_enum()); - (adt_def.did, last) - } else if last >= 1 && segments[last - 1].args.is_some() { - // Everything but the penultimate segment should have no - // parameters at all. - let enum_def_id = self.tcx.parent_def_id(def_id).unwrap(); - (enum_def_id, last - 1) - } else { - // FIXME: lint here suggesting `Enum::<...>::Variant` form - // instead of `Enum::Variant::<...>` form. - - // Everything but the final segment should have no - // parameters at all. - let generics = self.tcx.generics_of(def_id); - // Variant and struct constructors use the - // generics of their parent type definition. - (generics.parent.unwrap_or(def_id), last) - }; - path_segs.push(PathSeg(generics_def_id, index)); - } - - // Case 3. Reference to a top-level value. - Def::Fn(def_id) | - Def::Const(def_id) | - Def::Static(def_id, _) => { - path_segs.push(PathSeg(def_id, last)); - } - - // Case 4. Reference to a method or associated const. - Def::Method(def_id) | - Def::AssociatedConst(def_id) => { - if segments.len() >= 2 { - let generics = self.tcx.generics_of(def_id); - path_segs.push(PathSeg(generics.parent.unwrap(), last - 1)); - } - path_segs.push(PathSeg(def_id, last)); - } - - // Case 5. Local variable, no generics. - Def::Local(..) | Def::Upvar(..) => {} - - _ => bug!("unexpected definition: {:?}", def), - } - - debug!("path_segs = {:?}", path_segs); - - path_segs - } - // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. pub fn instantiate_value_path(&self, @@ -5204,7 +5076,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; - let path_segs = self.def_ids_for_path_segments(segments, self_ty, def); + let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def); let mut user_self_ty = None; match def { diff --git a/src/test/run-pass/enum-variant-generic-args.rs b/src/test/run-pass/enum-variant-generic-args.rs index bb4a4c9cf0c0c..ace4ebdfa0595 100644 --- a/src/test/run-pass/enum-variant-generic-args.rs +++ b/src/test/run-pass/enum-variant-generic-args.rs @@ -8,9 +8,9 @@ type Alias = Enum; type AliasFixed = Enum<()>; macro_rules! is_variant { - (TSVariant, $expr:expr) => (is_variant!(@TSVariant, (_), $expr)); - (SVariant, $expr:expr) => (is_variant!(@SVariant, { v: _ }, $expr)); - (@$variant:ident, $matcher:tt, $expr:expr) => ( + (TSVariant, $expr:expr) => (is_variant!(@check TSVariant, (_), $expr)); + (SVariant, $expr:expr) => (is_variant!(@check SVariant, { v: _ }, $expr)); + (@check $variant:ident, $matcher:tt, $expr:expr) => ( assert!(if let Enum::$variant::<()> $matcher = $expr { true } else { false }, "expr does not have correct type"); ); diff --git a/src/test/ui/enum-variant-generic-args.rs b/src/test/ui/enum-variant-generic-args.rs index 2ae4b756b7c05..044d8438815ba 100644 --- a/src/test/ui/enum-variant-generic-args.rs +++ b/src/test/ui/enum-variant-generic-args.rs @@ -16,13 +16,16 @@ impl Enum { } fn s_variant() { - Self::SVariant::<()>(()); + Self::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] - Self::<()>::SVariant(()); + //~^^ ERROR mismatched types [E0308] + Self::<()>::SVariant { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] - Self::<()>::SVariant::<()>(()); + //~^^ ERROR mismatched types [E0308] + Self::<()>::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] //~^^ ERROR type arguments are not allowed on this entity [E0109] + //~^^^ ERROR mismatched types [E0308] } } @@ -47,19 +50,19 @@ fn main() { // Struct variant - Enum::<()>::SVariant::<()>(()); + Enum::<()>::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] - Alias::SVariant::<()>(()); + Alias::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] - Alias::<()>::SVariant::<()>(()); + Alias::<()>::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] - AliasFixed::SVariant::<()>(()); + AliasFixed::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] - AliasFixed::<()>::SVariant(()); + AliasFixed::<()>::SVariant { v: () }; //~^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] - AliasFixed::<()>::SVariant::<()>(()); + AliasFixed::<()>::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] //~^^ ERROR wrong number of type arguments: expected 0, found 1 [E0107] } diff --git a/src/test/ui/enum-variant-generic-args.stderr b/src/test/ui/enum-variant-generic-args.stderr index 2d622a49e20af..4228a807bad16 100644 --- a/src/test/ui/enum-variant-generic-args.stderr +++ b/src/test/ui/enum-variant-generic-args.stderr @@ -1,12 +1,3 @@ -error[E0423]: expected function, found struct variant `Enum::SVariant` - --> $DIR/enum-variant-generic-args.rs:50:5 - | -LL | Enum::<()>::SVariant::<()>(()); - | ^^^^^^^^^^^^--------^^^^^^ - | | | - | | did you mean `TSVariant`? - | did you mean `Enum::SVariant { /* fields */ }`? - error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:9:27 | @@ -34,226 +25,139 @@ LL | Self::<()>::TSVariant::<()>(()); error[E0109]: type arguments are not allowed on this entity --> $DIR/enum-variant-generic-args.rs:19:26 | -LL | Self::SVariant::<()>(()); +LL | Self::SVariant::<()> { v: () }; | ^^ type argument not allowed -error[E0618]: expected function, found enum variant `::SVariant::<()>` - --> $DIR/enum-variant-generic-args.rs:19:9 +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:19:35 | -LL | enum Enum { TSVariant(T), SVariant { v: T } } - | ----------------- `::SVariant::<()>` defined here -... -LL | Self::SVariant::<()>(()); - | ^^^^^^^^^^^^^^^^^^^^---- - | | - | call expression requires function -help: `::SVariant::<()>` is a unit variant, you need to write it without the parenthesis +LL | Self::SVariant::<()> { v: () }; + | ^^ expected type parameter, found () | -LL | ::SVariant::<()>; - | ^^^^^^^^^^^^^^^^^^^^^^ + = note: expected type `T` + found type `()` error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:21:16 + --> $DIR/enum-variant-generic-args.rs:22:16 | -LL | Self::<()>::SVariant(()); +LL | Self::<()>::SVariant { v: () }; | ^^ type argument not allowed -error[E0618]: expected function, found enum variant `>::SVariant` - --> $DIR/enum-variant-generic-args.rs:21:9 +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:22:35 | -LL | enum Enum { TSVariant(T), SVariant { v: T } } - | ----------------- `>::SVariant` defined here -... -LL | Self::<()>::SVariant(()); - | ^^^^^^^^^^^^^^^^^^^^---- - | | - | call expression requires function -help: `>::SVariant` is a unit variant, you need to write it without the parenthesis +LL | Self::<()>::SVariant { v: () }; + | ^^ expected type parameter, found () | -LL | >::SVariant; - | ^^^^^^^^^^^^^^^^^^^^ + = note: expected type `T` + found type `()` error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:23:16 + --> $DIR/enum-variant-generic-args.rs:25:16 | -LL | Self::<()>::SVariant::<()>(()); +LL | Self::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:23:32 + --> $DIR/enum-variant-generic-args.rs:25:32 | -LL | Self::<()>::SVariant::<()>(()); +LL | Self::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed -error[E0618]: expected function, found enum variant `>::SVariant::<()>` - --> $DIR/enum-variant-generic-args.rs:23:9 +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:25:41 | -LL | enum Enum { TSVariant(T), SVariant { v: T } } - | ----------------- `>::SVariant::<()>` defined here -... -LL | Self::<()>::SVariant::<()>(()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^---- - | | - | call expression requires function -help: `>::SVariant::<()>` is a unit variant, you need to write it without the parenthesis +LL | Self::<()>::SVariant::<()> { v: () }; + | ^^ expected type parameter, found () | -LL | >::SVariant::<()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ + = note: expected type `T` + found type `()` error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:32:29 + --> $DIR/enum-variant-generic-args.rs:35:29 | LL | Enum::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:35:24 + --> $DIR/enum-variant-generic-args.rs:38:24 | LL | Alias::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:37:30 + --> $DIR/enum-variant-generic-args.rs:40:30 | LL | Alias::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:40:29 + --> $DIR/enum-variant-generic-args.rs:43:29 | LL | AliasFixed::TSVariant::<()>(()); | ^^ type argument not allowed error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:42:18 + --> $DIR/enum-variant-generic-args.rs:45:18 | LL | AliasFixed::<()>::TSVariant(()); | ^^ unexpected type argument error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:44:18 + --> $DIR/enum-variant-generic-args.rs:47:18 | LL | AliasFixed::<()>::TSVariant::<()>(()); | ^^ unexpected type argument error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:44:35 + --> $DIR/enum-variant-generic-args.rs:47:35 | LL | AliasFixed::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:53:23 + --> $DIR/enum-variant-generic-args.rs:53:28 | -LL | Alias::SVariant::<()>(()); - | ^^ type argument not allowed +LL | Enum::<()>::SVariant::<()> { v: () }; + | ^^ type argument not allowed -error[E0618]: expected function, found enum variant `::SVariant::<()>` - --> $DIR/enum-variant-generic-args.rs:53:5 - | -LL | enum Enum { TSVariant(T), SVariant { v: T } } - | ----------------- `::SVariant::<()>` defined here -... -LL | Alias::SVariant::<()>(()); - | ^^^^^^^^^^^^^^^^^^^^^---- - | | - | call expression requires function -help: `::SVariant::<()>` is a unit variant, you need to write it without the parenthesis +error[E0109]: type arguments are not allowed on this entity + --> $DIR/enum-variant-generic-args.rs:56:23 | -LL | ::SVariant::<()>; - | ^^^^^^^^^^^^^^^^^^^^^^^ +LL | Alias::SVariant::<()> { v: () }; + | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:55:29 + --> $DIR/enum-variant-generic-args.rs:58:29 | -LL | Alias::<()>::SVariant::<()>(()); +LL | Alias::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed -error[E0618]: expected function, found enum variant `>::SVariant::<()>` - --> $DIR/enum-variant-generic-args.rs:55:5 - | -LL | enum Enum { TSVariant(T), SVariant { v: T } } - | ----------------- `>::SVariant::<()>` defined here -... -LL | Alias::<()>::SVariant::<()>(()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^---- - | | - | call expression requires function -help: `>::SVariant::<()>` is a unit variant, you need to write it without the parenthesis - | -LL | >::SVariant::<()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:58:28 + --> $DIR/enum-variant-generic-args.rs:61:28 | -LL | AliasFixed::SVariant::<()>(()); +LL | AliasFixed::SVariant::<()> { v: () }; | ^^ type argument not allowed -error[E0618]: expected function, found enum variant `::SVariant::<()>` - --> $DIR/enum-variant-generic-args.rs:58:5 - | -LL | enum Enum { TSVariant(T), SVariant { v: T } } - | ----------------- `::SVariant::<()>` defined here -... -LL | AliasFixed::SVariant::<()>(()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^---- - | | - | call expression requires function -help: `::SVariant::<()>` is a unit variant, you need to write it without the parenthesis - | -LL | ::SVariant::<()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:60:18 + --> $DIR/enum-variant-generic-args.rs:63:18 | -LL | AliasFixed::<()>::SVariant(()); +LL | AliasFixed::<()>::SVariant { v: () }; | ^^ unexpected type argument -error[E0618]: expected function, found enum variant `>::SVariant` - --> $DIR/enum-variant-generic-args.rs:60:5 - | -LL | enum Enum { TSVariant(T), SVariant { v: T } } - | ----------------- `>::SVariant` defined here -... -LL | AliasFixed::<()>::SVariant(()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^---- - | | - | call expression requires function -help: `>::SVariant` is a unit variant, you need to write it without the parenthesis - | -LL | >::SVariant; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:62:18 + --> $DIR/enum-variant-generic-args.rs:65:18 | -LL | AliasFixed::<()>::SVariant::<()>(()); +LL | AliasFixed::<()>::SVariant::<()> { v: () }; | ^^ unexpected type argument error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:62:34 + --> $DIR/enum-variant-generic-args.rs:65:34 | -LL | AliasFixed::<()>::SVariant::<()>(()); +LL | AliasFixed::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed -error[E0618]: expected function, found enum variant `>::SVariant::<()>` - --> $DIR/enum-variant-generic-args.rs:62:5 - | -LL | enum Enum { TSVariant(T), SVariant { v: T } } - | ----------------- `>::SVariant::<()>` defined here -... -LL | AliasFixed::<()>::SVariant::<()>(()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^---- - | | - | call expression requires function -help: `>::SVariant::<()>` is a unit variant, you need to write it without the parenthesis - | -LL | >::SVariant::<()>; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 30 previous errors +error: aborting due to 25 previous errors -Some errors occurred: E0107, E0109, E0423, E0618. +Some errors occurred: E0107, E0109, E0308. For more information about an error, try `rustc --explain E0107`. From 6a3f96d3027308f18037d2291700f23fa1adce19 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 20 Dec 2018 03:26:07 +0000 Subject: [PATCH 17/22] Fixed type inference for tuple struct variants. --- src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/mod.rs | 17 +++++++++++------ src/test/run-pass/enum-variant-generic-args.rs | 15 +-------------- src/test/ui/enum-variant-generic-args.rs | 4 ++++ 4 files changed, 17 insertions(+), 21 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 98013dd00dc70..a68148515c425 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1551,7 +1551,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { // Case 2. Reference to a variant constructor. Def::Variant(def_id) | Def::VariantCtor(def_id, ..) => { - let adt_def = self_ty.and_then(|t| t.ty_adt_def()); + let adt_def = self_ty.map(|t| t.ty_adt_def().unwrap()); let (generics_def_id, index) = if let Some(adt_def) = adt_def { debug_assert!(adt_def.is_enum()); (adt_def.did, last) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 76fbe862211cf..e2eb7fab0f732 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5079,7 +5079,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def); let mut user_self_ty = None; + let mut is_alias_variant_ctor = false; match def { + Def::VariantCtor(_, _) => { + if let Some(self_ty) = self_ty { + let adt_def = self_ty.ty_adt_def().unwrap(); + user_self_ty = Some(UserSelfTy { + impl_def_id: adt_def.did, + self_ty, + }); + is_alias_variant_ctor = true; + } + } Def::Method(def_id) | Def::AssociatedConst(def_id) => { let container = tcx.associated_item(def_id).container; @@ -5111,12 +5122,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // provided (if any) into their appropriate spaces. We'll also report // errors if type parameters are provided in an inappropriate place. - let is_alias_variant_ctor = - match def { - Def::VariantCtor(_, _) if self_ty.is_some() => true, - _ => false, - }; - let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect(); AstConv::prohibit_generics(self, segments.iter().enumerate().filter_map(|(index, seg)| { if !generic_segs.contains(&index) || is_alias_variant_ctor { diff --git a/src/test/run-pass/enum-variant-generic-args.rs b/src/test/run-pass/enum-variant-generic-args.rs index ace4ebdfa0595..0743f99897922 100644 --- a/src/test/run-pass/enum-variant-generic-args.rs +++ b/src/test/run-pass/enum-variant-generic-args.rs @@ -3,6 +3,7 @@ #![allow(irrefutable_let_patterns)] +#[allow(dead_code)] enum Enum { TSVariant(T), SVariant { v: T } } type Alias = Enum; type AliasFixed = Enum<()>; @@ -16,16 +17,6 @@ macro_rules! is_variant { ); } -impl Enum { - fn ts_variant() { - is_variant!(TSVariant, Self::TSVariant(())); - } - - fn s_variant() { - is_variant!(SVariant, Self::SVariant { v: () }); - } -} - fn main() { // Tuple struct variant @@ -38,8 +29,6 @@ fn main() { is_variant!(TSVariant, AliasFixed::TSVariant(())); - Enum::<()>::ts_variant(); - // Struct variant is_variant!(SVariant, Enum::SVariant { v: () }); @@ -50,6 +39,4 @@ fn main() { is_variant!(SVariant, Alias::<()>::SVariant { v: () }); is_variant!(SVariant, AliasFixed::SVariant { v: () }); - - Enum::<()>::s_variant(); } diff --git a/src/test/ui/enum-variant-generic-args.rs b/src/test/ui/enum-variant-generic-args.rs index 044d8438815ba..ad821344e2143 100644 --- a/src/test/ui/enum-variant-generic-args.rs +++ b/src/test/ui/enum-variant-generic-args.rs @@ -6,6 +6,8 @@ type AliasFixed = Enum<()>; impl Enum { fn ts_variant() { + Self::TSVariant(()); + //~^ ERROR type parameters are not allowed on this name [E0109] Self::TSVariant::<()>(()); //~^ ERROR type arguments are not allowed on this entity [E0109] Self::<()>::TSVariant(()); @@ -16,6 +18,8 @@ impl Enum { } fn s_variant() { + Self::SVariant { v: () }; + //~^ ERROR type parameters are not allowed on this name [E0109] Self::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] //~^^ ERROR mismatched types [E0308] From 67a30d2d7038f5a2667d93205ba5341ca7566dff Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Thu, 20 Dec 2018 18:38:55 +0000 Subject: [PATCH 18/22] Fixed ICE when type arguments are specified on `Self` type. --- src/librustc_typeck/astconv.rs | 8 +- src/librustc_typeck/check/mod.rs | 10 ++- src/test/ui/enum-variant-generic-args.rs | 5 +- src/test/ui/enum-variant-generic-args.stderr | 79 +++++++++++++------- 4 files changed, 71 insertions(+), 31 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index a68148515c425..f819a5f642fcb 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1431,7 +1431,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { self.normalize_ty(span, tcx.mk_projection(item_def_id, trait_ref.substs)) } - pub fn prohibit_generics<'a, T: IntoIterator>(&self, segments: T) { + pub fn prohibit_generics<'a, T: IntoIterator>( + &self, segments: T) -> bool { + let mut has_err = false; for segment in segments { segment.with_generic_args(|generic_args| { let (mut err_for_lt, mut err_for_ty) = (false, false); @@ -1440,6 +1442,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { hir::GenericArg::Lifetime(lt) => { if err_for_lt { continue } err_for_lt = true; + has_err = true; (struct_span_err!(self.tcx().sess, lt.span, E0110, "lifetime arguments are not allowed on this entity"), lt.span, @@ -1448,6 +1451,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { hir::GenericArg::Type(ty) => { if err_for_ty { continue } err_for_ty = true; + has_err = true; (struct_span_err!(self.tcx().sess, ty.span, E0109, "type arguments are not allowed on this entity"), ty.span, @@ -1461,11 +1465,13 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } } for binding in &generic_args.bindings { + has_err = true; Self::prohibit_assoc_ty_binding(self.tcx(), binding.span); break; } }) } + has_err } pub fn prohibit_assoc_ty_binding(tcx: TyCtxt, span: Span) { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e2eb7fab0f732..c2b4078e91f15 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5123,13 +5123,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // errors if type parameters are provided in an inappropriate place. let generic_segs: FxHashSet<_> = path_segs.iter().map(|PathSeg(_, index)| index).collect(); - AstConv::prohibit_generics(self, segments.iter().enumerate().filter_map(|(index, seg)| { + let generics_has_err = AstConv::prohibit_generics( + self, segments.iter().enumerate().filter_map(|(index, seg)| { if !generic_segs.contains(&index) || is_alias_variant_ctor { Some(seg) } else { None } })); + if generics_has_err { + // Don't try to infer type parameters when prohibited generic arguments were given. + user_self_ty = None; + } match def { Def::Local(nid) | Def::Upvar(nid, ..) => { @@ -5301,9 +5306,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if let Some(UserSelfTy { impl_def_id, self_ty }) = user_self_ty { // In the case of `Foo::method` and `>::method`, if `method` - // is inherent, there is no `Self` parameter, instead, the impl needs + // is inherent, there is no `Self` parameter; instead, the impl needs // type parameters, which we can infer by unifying the provided `Self` // with the substituted impl type. + // This also occurs for an enum variant on a type alias. let ty = tcx.type_of(impl_def_id); let impl_ty = self.instantiate_type_scheme(span, &substs, &ty); diff --git a/src/test/ui/enum-variant-generic-args.rs b/src/test/ui/enum-variant-generic-args.rs index ad821344e2143..6eddd70964546 100644 --- a/src/test/ui/enum-variant-generic-args.rs +++ b/src/test/ui/enum-variant-generic-args.rs @@ -7,11 +7,12 @@ type AliasFixed = Enum<()>; impl Enum { fn ts_variant() { Self::TSVariant(()); - //~^ ERROR type parameters are not allowed on this name [E0109] + //~^ ERROR mismatched types [E0308] Self::TSVariant::<()>(()); //~^ ERROR type arguments are not allowed on this entity [E0109] Self::<()>::TSVariant(()); //~^ ERROR type arguments are not allowed on this entity [E0109] + //~^^ ERROR mismatched types [E0308] Self::<()>::TSVariant::<()>(()); //~^ ERROR type arguments are not allowed on this entity [E0109] //~^^ ERROR type arguments are not allowed on this entity [E0109] @@ -19,7 +20,7 @@ impl Enum { fn s_variant() { Self::SVariant { v: () }; - //~^ ERROR type parameters are not allowed on this name [E0109] + //~^ ERROR mismatched types [E0308] Self::SVariant::<()> { v: () }; //~^ ERROR type arguments are not allowed on this entity [E0109] //~^^ ERROR mismatched types [E0308] diff --git a/src/test/ui/enum-variant-generic-args.stderr b/src/test/ui/enum-variant-generic-args.stderr index 4228a807bad16..4d3b576734643 100644 --- a/src/test/ui/enum-variant-generic-args.stderr +++ b/src/test/ui/enum-variant-generic-args.stderr @@ -1,35 +1,62 @@ +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:9:25 + | +LL | Self::TSVariant(()); + | ^^ expected type parameter, found () + | + = note: expected type `T` + found type `()` + error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:9:27 + --> $DIR/enum-variant-generic-args.rs:11:27 | LL | Self::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:11:16 + --> $DIR/enum-variant-generic-args.rs:13:16 | LL | Self::<()>::TSVariant(()); | ^^ type argument not allowed +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:13:31 + | +LL | Self::<()>::TSVariant(()); + | ^^ expected type parameter, found () + | + = note: expected type `T` + found type `()` + error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:13:16 + --> $DIR/enum-variant-generic-args.rs:16:16 | LL | Self::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:13:33 + --> $DIR/enum-variant-generic-args.rs:16:33 | LL | Self::<()>::TSVariant::<()>(()); | ^^ type argument not allowed +error[E0308]: mismatched types + --> $DIR/enum-variant-generic-args.rs:22:29 + | +LL | Self::SVariant { v: () }; + | ^^ expected type parameter, found () + | + = note: expected type `T` + found type `()` + error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:19:26 + --> $DIR/enum-variant-generic-args.rs:24:26 | LL | Self::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0308]: mismatched types - --> $DIR/enum-variant-generic-args.rs:19:35 + --> $DIR/enum-variant-generic-args.rs:24:35 | LL | Self::SVariant::<()> { v: () }; | ^^ expected type parameter, found () @@ -38,13 +65,13 @@ LL | Self::SVariant::<()> { v: () }; found type `()` error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:22:16 + --> $DIR/enum-variant-generic-args.rs:27:16 | LL | Self::<()>::SVariant { v: () }; | ^^ type argument not allowed error[E0308]: mismatched types - --> $DIR/enum-variant-generic-args.rs:22:35 + --> $DIR/enum-variant-generic-args.rs:27:35 | LL | Self::<()>::SVariant { v: () }; | ^^ expected type parameter, found () @@ -53,19 +80,19 @@ LL | Self::<()>::SVariant { v: () }; found type `()` error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:25:16 + --> $DIR/enum-variant-generic-args.rs:30:16 | LL | Self::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:25:32 + --> $DIR/enum-variant-generic-args.rs:30:32 | LL | Self::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0308]: mismatched types - --> $DIR/enum-variant-generic-args.rs:25:41 + --> $DIR/enum-variant-generic-args.rs:30:41 | LL | Self::<()>::SVariant::<()> { v: () }; | ^^ expected type parameter, found () @@ -74,90 +101,90 @@ LL | Self::<()>::SVariant::<()> { v: () }; found type `()` error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:35:29 + --> $DIR/enum-variant-generic-args.rs:40:29 | LL | Enum::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:38:24 + --> $DIR/enum-variant-generic-args.rs:43:24 | LL | Alias::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:40:30 + --> $DIR/enum-variant-generic-args.rs:45:30 | LL | Alias::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:43:29 + --> $DIR/enum-variant-generic-args.rs:48:29 | LL | AliasFixed::TSVariant::<()>(()); | ^^ type argument not allowed error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:45:18 + --> $DIR/enum-variant-generic-args.rs:50:18 | LL | AliasFixed::<()>::TSVariant(()); | ^^ unexpected type argument error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:47:18 + --> $DIR/enum-variant-generic-args.rs:52:18 | LL | AliasFixed::<()>::TSVariant::<()>(()); | ^^ unexpected type argument error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:47:35 + --> $DIR/enum-variant-generic-args.rs:52:35 | LL | AliasFixed::<()>::TSVariant::<()>(()); | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:53:28 + --> $DIR/enum-variant-generic-args.rs:58:28 | LL | Enum::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:56:23 + --> $DIR/enum-variant-generic-args.rs:61:23 | LL | Alias::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:58:29 + --> $DIR/enum-variant-generic-args.rs:63:29 | LL | Alias::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:61:28 + --> $DIR/enum-variant-generic-args.rs:66:28 | LL | AliasFixed::SVariant::<()> { v: () }; | ^^ type argument not allowed error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:63:18 + --> $DIR/enum-variant-generic-args.rs:68:18 | LL | AliasFixed::<()>::SVariant { v: () }; | ^^ unexpected type argument error[E0107]: wrong number of type arguments: expected 0, found 1 - --> $DIR/enum-variant-generic-args.rs:65:18 + --> $DIR/enum-variant-generic-args.rs:70:18 | LL | AliasFixed::<()>::SVariant::<()> { v: () }; | ^^ unexpected type argument error[E0109]: type arguments are not allowed on this entity - --> $DIR/enum-variant-generic-args.rs:65:34 + --> $DIR/enum-variant-generic-args.rs:70:34 | LL | AliasFixed::<()>::SVariant::<()> { v: () }; | ^^ type argument not allowed -error: aborting due to 25 previous errors +error: aborting due to 28 previous errors Some errors occurred: E0107, E0109, E0308. For more information about an error, try `rustc --explain E0107`. From 87532e99e5ff2d63e78d7b67cae8c65d12ce5995 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Wed, 26 Dec 2018 00:07:31 +0000 Subject: [PATCH 19/22] Minor clean-up --- src/librustc_typeck/astconv.rs | 22 ++++++++++++---------- src/librustc_typeck/check/method/mod.rs | 7 ++++--- 2 files changed, 16 insertions(+), 13 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index f819a5f642fcb..80583a5855864 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -569,7 +569,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { let has_self = generic_params.has_self; let (_, potential_assoc_types) = Self::check_generic_arg_count( - self.tcx(), + tcx, span, &generic_params, &generic_args, @@ -594,7 +594,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { }; let substs = Self::create_substs_for_generic_args( - self.tcx(), + tcx, def_id, &[][..], self_ty.is_some(), @@ -1293,8 +1293,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { self.prohibit_generics(slice::from_ref(item_segment)); // Check if we have an enum variant here. - if let ty::Adt(adt_def, _) = ty.sty { - if adt_def.is_enum() { + match ty.sty { + ty::Adt(adt_def, _) if adt_def.is_enum() => { let variant_def = adt_def.variants.iter().find(|vd| { tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) }); @@ -1305,7 +1305,8 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { tcx.check_stability(def.def_id(), Some(ref_id), span); return (ty, def); } - } + }, + _ => (), } // Find the type of the associated item, and the trait where the associated @@ -1339,7 +1340,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { } (&ty::Adt(adt_def, _substs), Def::Enum(_did)) => { let ty_str = ty.to_string(); - // Incorrect enum variant + // Incorrect enum variant. let mut err = tcx.sess.struct_span_err( span, &format!("no variant `{}` on enum `{}`", &assoc_name.as_str(), ty_str), @@ -1669,23 +1670,24 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { tcx.mk_ty_param(index, tcx.hir().name(node_id).as_interned_str()) } Def::SelfTy(_, Some(def_id)) => { - // `Self` in impl (we know the concrete type) + // `Self` in impl (we know the concrete type). assert_eq!(opt_self_ty, None); self.prohibit_generics(&path.segments); tcx.at(span).type_of(def_id) } Def::SelfTy(Some(_), None) => { - // `Self` in trait + // `Self` in trait. assert_eq!(opt_self_ty, None); self.prohibit_generics(&path.segments); tcx.mk_self_type() } Def::AssociatedTy(def_id) => { - self.prohibit_generics(&path.segments[..path.segments.len()-2]); + debug_assert!(path.segments.len() >= 2); + self.prohibit_generics(&path.segments[..path.segments.len() - 2]); self.qpath_to_ty(span, opt_self_ty, def_id, - &path.segments[path.segments.len()-2], + &path.segments[path.segments.len() - 2], path.segments.last().unwrap()) } Def::PrimTy(prim_ty) => { diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 88814ae6a2db9..a039835b88f81 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -372,8 +372,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; // Check if we have an enum variant here. - if let ty::Adt(adt_def, _) = self_ty.sty { - if adt_def.is_enum() { + match self_ty.sty { + ty::Adt(adt_def, _) if adt_def.is_enum() => { let variant_def = adt_def.variants.iter().find(|vd| { tcx.hygienic_eq(method_name, vd.ident, adt_def.did) }); @@ -384,7 +384,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.check_stability(def.def_id(), Some(expr_id), span); return Ok(def); } - } + }, + _ => (), } let mode = probe::Mode::Path; From ab239f37aaade0764ee1ace12828d2f766600296 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Wed, 26 Dec 2018 16:15:42 +0000 Subject: [PATCH 20/22] Minor cosmetic changes --- src/librustc_typeck/check/_match.rs | 6 +++--- src/librustc_typeck/check/mod.rs | 13 +++++++------ 2 files changed, 10 insertions(+), 9 deletions(-) diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index 923be2a76aa66..b66c383edb51e 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -275,7 +275,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { PatKind::Tuple(ref elements, ddpos) => { let mut expected_len = elements.len(); if ddpos.is_some() { - // Require known type only when `..` is present + // Require known type only when `..` is present. if let ty::Tuple(ref tys) = self.structurally_resolved_type(pat.span, expected).sty { expected_len = tys.len(); @@ -284,8 +284,8 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let max_len = cmp::max(expected_len, elements.len()); let element_tys_iter = (0..max_len).map(|_| self.next_ty_var( - // FIXME: MiscVariable for now, obtaining the span and name information - // from all tuple elements isn't trivial. + // FIXME: `MiscVariable` for now -- obtaining the span and name information + // from all tuple elements isn't trivial. TypeVariableOrigin::TypeInference(pat.span))); let element_tys = tcx.mk_type_list(element_tys_iter); let pat_ty = tcx.mk_ty(ty::Tuple(element_tys)); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index c2b4078e91f15..060b37fa0b87f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4615,7 +4615,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { local: &'gcx hir::Local, init: &'gcx hir::Expr) -> Ty<'tcx> { - // FIXME(tschottdorf): contains_explicit_ref_binding() must be removed + // FIXME(tschottdorf): `contains_explicit_ref_binding()` must be removed // for #42640 (default match binding modes). // // See #44848. @@ -4660,7 +4660,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } pub fn check_stmt(&self, stmt: &'gcx hir::Stmt) { - // Don't do all the complex logic below for DeclItem. + // Don't do all the complex logic below for `DeclItem`. match stmt.node { hir::StmtKind::Decl(ref decl, _) => { if let hir::DeclKind::Item(_) = decl.node { @@ -4672,7 +4672,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.warn_if_unreachable(stmt.node.id(), stmt.span, "statement"); - // Hide the outer diverging and has_errors flags. + // Hide the outer diverging and `has_errors` flags. let old_diverges = self.diverges.get(); let old_has_errors = self.has_errors.get(); self.diverges.set(Diverges::Maybe); @@ -4684,11 +4684,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { hir::DeclKind::Local(ref l) => { self.check_decl_local(&l); } - hir::DeclKind::Item(_) => {/* ignore for now */} + // Ignore for now. + hir::DeclKind::Item(_) => () } } hir::StmtKind::Expr(ref expr, _) => { - // Check with expected type of () + // Check with expected type of `()`. self.check_expr_has_type_or_error(&expr, self.tcx.mk_unit()); } hir::StmtKind::Semi(ref expr, _) => { @@ -4696,7 +4697,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } - // Combine the diverging and has_error flags. + // Combine the diverging and `has_error` flags. self.diverges.set(self.diverges.get() | old_diverges); self.has_errors.set(self.has_errors.get() | old_has_errors); } From 5adf8c358ad70f9a50536a0bd47f938cb0aaea18 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Wed, 26 Dec 2018 16:38:35 +0000 Subject: [PATCH 21/22] Changed resolution of enum variants to low priority. --- src/librustc_typeck/astconv.rs | 36 +++++++-------- src/librustc_typeck/check/method/mod.rs | 61 +++++++++++++------------ src/test/ui/bogus-tag.stderr | 4 +- 3 files changed, 53 insertions(+), 48 deletions(-) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 80583a5855864..1db7141917f98 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1292,28 +1292,11 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { self.prohibit_generics(slice::from_ref(item_segment)); - // Check if we have an enum variant here. - match ty.sty { - ty::Adt(adt_def, _) if adt_def.is_enum() => { - let variant_def = adt_def.variants.iter().find(|vd| { - tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) - }); - if let Some(variant_def) = variant_def { - check_type_alias_enum_variants_enabled(tcx, span); - - let def = Def::Variant(variant_def.did); - tcx.check_stability(def.def_id(), Some(ref_id), span); - return (ty, def); - } - }, - _ => (), - } - // Find the type of the associated item, and the trait where the associated // item is declared. let bound = match (&ty.sty, ty_path_def) { (_, Def::SelfTy(Some(_), Some(impl_def_id))) => { - // `Self` in an impl of a trait -- we have a concrete `self` type and a + // `Self` in an impl of a trait -- we have a concrete self type and a // trait reference. let trait_ref = match tcx.impl_trait_ref(impl_def_id) { Some(trait_ref) => trait_ref, @@ -1365,6 +1348,23 @@ impl<'o, 'gcx: 'tcx, 'tcx> dyn AstConv<'gcx, 'tcx> + 'o { return (tcx.types.err, Def::Err); } _ => { + // Check if we have an enum variant. + match ty.sty { + ty::Adt(adt_def, _) if adt_def.is_enum() => { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(assoc_name, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + check_type_alias_enum_variants_enabled(tcx, span); + + let def = Def::Variant(variant_def.did); + tcx.check_stability(def.def_id(), Some(ref_id), span); + return (ty, def); + } + }, + _ => (), + } + // Don't print `TyErr` to the user. if !ty.references_error() { self.report_ambiguous_associated_type(span, diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index a039835b88f81..fe5f43e3c01ef 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -371,38 +371,43 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; - // Check if we have an enum variant here. - match self_ty.sty { - ty::Adt(adt_def, _) if adt_def.is_enum() => { - let variant_def = adt_def.variants.iter().find(|vd| { - tcx.hygienic_eq(method_name, vd.ident, adt_def.did) - }); - if let Some(variant_def) = variant_def { - check_type_alias_enum_variants_enabled(tcx, span); - - let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); - tcx.check_stability(def.def_id(), Some(expr_id), span); - return Ok(def); + let mode = probe::Mode::Path; + match self.probe_for_name(span, mode, method_name, IsSuggestion(false), + self_ty, expr_id, ProbeScope::TraitsInScope) { + Ok(pick) => { + if let Some(import_id) = pick.import_id { + let import_def_id = tcx.hir().local_def_id(import_id); + debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id); + Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) + .unwrap().insert(import_def_id); } - }, - _ => (), - } - let mode = probe::Mode::Path; - let pick = self.probe_for_name(span, mode, method_name, IsSuggestion(false), - self_ty, expr_id, ProbeScope::TraitsInScope)?; + let def = pick.item.def(); + tcx.check_stability(def.def_id(), Some(expr_id), span); - if let Some(import_id) = pick.import_id { - let import_def_id = tcx.hir().local_def_id(import_id); - debug!("resolve_ufcs: used_trait_import: {:?}", import_def_id); - Lrc::get_mut(&mut self.tables.borrow_mut().used_trait_imports) - .unwrap().insert(import_def_id); - } - - let def = pick.item.def(); - tcx.check_stability(def.def_id(), Some(expr_id), span); + Ok(def) + } + Err(err) => { + // Check if we have an enum variant. + match self_ty.sty { + ty::Adt(adt_def, _) if adt_def.is_enum() => { + let variant_def = adt_def.variants.iter().find(|vd| { + tcx.hygienic_eq(method_name, vd.ident, adt_def.did) + }); + if let Some(variant_def) = variant_def { + check_type_alias_enum_variants_enabled(tcx, span); + + let def = Def::VariantCtor(variant_def.did, variant_def.ctor_kind); + tcx.check_stability(def.def_id(), Some(expr_id), span); + return Ok(def); + } + }, + _ => (), + } - Ok(def) + Err(err) + } + } } /// Find item with name `item_name` defined in impl/trait `def_id` diff --git a/src/test/ui/bogus-tag.stderr b/src/test/ui/bogus-tag.stderr index 1cb5ee9b6305c..3750df841720c 100644 --- a/src/test/ui/bogus-tag.stderr +++ b/src/test/ui/bogus-tag.stderr @@ -1,11 +1,11 @@ error[E0599]: no variant named `Hsl` found for type `Color` in the current scope - --> $DIR/bogus-tag.rs:7:9 + --> $DIR/bogus-tag.rs:7:16 | LL | enum Color { Rgb(isize, isize, isize), Rgba(isize, isize, isize, isize), } | ---------- variant `Hsl` not found here ... LL | Color::Hsl(h, s, l) => { println!("hsl"); } - | ^^^^^^^^^^^^^^^^^^^ variant not found in `Color` + | -------^^^--------- variant not found in `Color` error: aborting due to previous error From a4fa7ef2b90880623499e86324b7b40626a02f9d Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 29 Dec 2018 05:45:45 +0000 Subject: [PATCH 22/22] Fixed stderr files for ui tests. --- src/test/ui/error-codes/E0110.rs | 3 +-- src/test/ui/error-codes/E0110.stderr | 8 -------- .../rfc1598-generic-associated-types/collections.stderr | 4 ++-- 3 files changed, 3 insertions(+), 12 deletions(-) diff --git a/src/test/ui/error-codes/E0110.rs b/src/test/ui/error-codes/E0110.rs index 2de5da16ad76a..764b62b8dfecf 100644 --- a/src/test/ui/error-codes/E0110.rs +++ b/src/test/ui/error-codes/E0110.rs @@ -1,4 +1,3 @@ type X = u32<'static>; //~ ERROR E0110 -fn main() { -} +fn main() {} diff --git a/src/test/ui/error-codes/E0110.stderr b/src/test/ui/error-codes/E0110.stderr index be9b4229aeb60..a644ac92cefbf 100644 --- a/src/test/ui/error-codes/E0110.stderr +++ b/src/test/ui/error-codes/E0110.stderr @@ -1,13 +1,5 @@ -<<<<<<< HEAD error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/E0110.rs:1:14 -||||||| merged common ancestors -error[E0110]: lifetime parameters are not allowed on this type - --> $DIR/E0110.rs:11:14 -======= -error[E0110]: lifetime arguments are not allowed on this entity - --> $DIR/E0110.rs:11:14 ->>>>>>> Added regression test for using generic parameters on modules. | LL | type X = u32<'static>; //~ ERROR E0110 | ^^^^^^^ lifetime argument not allowed diff --git a/src/test/ui/rfc1598-generic-associated-types/collections.stderr b/src/test/ui/rfc1598-generic-associated-types/collections.stderr index b3fb81b418e8c..eeed04bd89213 100644 --- a/src/test/ui/rfc1598-generic-associated-types/collections.stderr +++ b/src/test/ui/rfc1598-generic-associated-types/collections.stderr @@ -22,13 +22,13 @@ error[E0109]: type arguments are not allowed on this entity LL | <>::Family as CollectionFamily>::Member; | ^ type argument not allowed -error[E0109]: type arguments are not allowed on this entity +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/collections.rs:24:50 | LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter>; | ^^^^^ lifetime argument not allowed -error[E0109]: type arguments are not allowed on this entity +error[E0110]: lifetime arguments are not allowed on this entity --> $DIR/collections.rs:50:50 | LL | fn iterate<'iter>(&'iter self) -> Self::Iter<'iter> {