From 12f029b7eecc01a38fbeec0eebe9041aa1bab7a5 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 02:07:13 +0100 Subject: [PATCH 01/19] Fix deref impl on type alias --- src/librustdoc/clean/inline.rs | 18 ++++++++++++ src/librustdoc/clean/mod.rs | 24 ++++++++++++++-- src/librustdoc/clean/types.rs | 8 ++++++ src/librustdoc/html/render.rs | 24 +++++++++++----- src/librustdoc/html/render/cache.rs | 43 +++++++++++++++++------------ 5 files changed, 90 insertions(+), 27 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c7e0f1e9e704b..fc75bf35b250d 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -273,6 +273,24 @@ fn build_type_alias(cx: &DocContext<'_>, did: DefId) -> clean::Typedef { clean::Typedef { type_: cx.tcx.type_of(did).clean(cx), generics: (cx.tcx.generics_of(did), predicates).clean(cx), + item_type: build_type_alias_type(cx, did), + } +} + +fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option { + let type_ = cx.tcx.type_of(did).clean(cx); + type_.def_id().and_then(|did| build_ty(cx, did)) +} + +pub fn build_ty(cx: &DocContext, did: DefId) -> Option { + match cx.tcx.def_kind(did)? { + DefKind::Struct | + DefKind::Union | + DefKind::Enum | + DefKind::Const | + DefKind::Static => Some(cx.tcx.type_of(did).clean(cx)), + DefKind::TyAlias => build_type_alias_type(cx, did), + _ => None, } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index be9654612f504..0cc4c55f49be8 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1122,7 +1122,16 @@ impl Clean for hir::ImplItem<'_> { MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx)) } hir::ImplItemKind::TyAlias(ref ty) => { - TypedefItem(Typedef { type_: ty.clean(cx), generics: Generics::default() }, true) + let type_ = ty.clean(cx); + let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); + TypedefItem( + Typedef { + type_, + generics: Generics::default(), + item_type, + }, + true, + ) } hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem( OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() }, @@ -1282,10 +1291,13 @@ impl Clean for ty::AssocItem { AssocTypeItem(bounds, ty.clean(cx)) } else { + let type_ = cx.tcx.type_of(self.def_id).clean(cx); + let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); TypedefItem( Typedef { - type_: cx.tcx.type_of(self.def_id).clean(cx), + type_, generics: Generics { params: Vec::new(), where_predicates: Vec::new() }, + item_type, }, true, ) @@ -1989,6 +2001,8 @@ impl Clean for ast::Name { impl Clean for doctree::Typedef<'_> { fn clean(&self, cx: &DocContext<'_>) -> Item { + let type_ = self.ty.clean(cx); + let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); Item { name: Some(self.name.clean(cx)), attrs: self.attrs.clean(cx), @@ -1998,7 +2012,11 @@ impl Clean for doctree::Typedef<'_> { stability: cx.stability(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx), inner: TypedefItem( - Typedef { type_: self.ty.clean(cx), generics: self.gen.clean(cx) }, + Typedef { + type_, + generics: self.gen.clean(cx), + item_type, + }, false, ), } diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 5d8e27ecadb82..79a078ca7a991 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1406,6 +1406,14 @@ pub struct PathSegment { pub struct Typedef { pub type_: Type, pub generics: Generics, + // Type of target item. + pub item_type: Option, +} + +impl GetDefId for Typedef { + fn def_id(&self) -> Option { + self.type_.def_id() + } } #[derive(Clone, Debug)] diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 2d932eb7668c4..69e268f3f80c1 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3469,22 +3469,27 @@ fn render_deref_methods( deref_mut: bool, ) { let deref_type = impl_.inner_impl().trait_.as_ref().unwrap(); - let target = impl_ + let (target, real_target) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => Some(&t.type_), + clean::TypedefItem(ref t, true) => { + Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }) + } _ => None, }) .next() .expect("Expected associated type binding"); let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; - if let Some(did) = target.def_id() { + if let Some(did) = real_target.def_id() { render_assoc_items(w, cx, container_item, did, what) } else { - if let Some(prim) = target.primitive_type() { + if let Some(prim) = real_target.primitive_type() { if let Some(&did) = cx.cache.primitive_locations.get(&prim) { render_assoc_items(w, cx, container_item, did, what); } @@ -4123,17 +4128,22 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some(target) = impl_ + if let Some((target, real_target)) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => Some(&t.type_), + clean::TypedefItem(ref t, true) => { + Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }) + } _ => None, }) .next() { - let inner_impl = target + let inner_impl = real_target .def_id() .or(target .primitive_type() diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index 22507443b0842..cdfd6b3073adf 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -277,7 +277,7 @@ impl DocFolder for Cache { | clean::StructFieldItem(..) | clean::VariantItem(..) => ( ( - Some(*self.parent_stack.last().unwrap()), + Some(*self.parent_stack.last().expect("parent_stack is empty")), Some(&self.stack[..self.stack.len() - 1]), ), false, @@ -286,7 +286,7 @@ impl DocFolder for Cache { if self.parent_stack.is_empty() { ((None, None), false) } else { - let last = self.parent_stack.last().unwrap(); + let last = self.parent_stack.last().expect("parent_stack is empty 2"); let did = *last; let path = match self.paths.get(&did) { // The current stack not necessarily has correlation @@ -468,7 +468,7 @@ impl DocFolder for Cache { self.impls.entry(did).or_insert(vec![]).push(impl_item.clone()); } } else { - let trait_did = impl_item.trait_did().unwrap(); + let trait_did = impl_item.trait_did().expect("no trait did"); self.orphan_trait_impls.push((trait_did, dids, impl_item)); } None @@ -478,10 +478,10 @@ impl DocFolder for Cache { }); if pushed { - self.stack.pop().unwrap(); + self.stack.pop().expect("stack already empty"); } if parent_pushed { - self.parent_stack.pop().unwrap(); + self.parent_stack.pop().expect("parent stack already empty"); } self.stripped_mod = orig_stripped_mod; self.parent_is_trait_impl = orig_parent_is_trait_impl; @@ -574,6 +574,9 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { // has since been learned. for &(did, ref item) in orphan_impl_items { if let Some(&(ref fqp, _)) = paths.get(&did) { + if item.name.is_none() { // this is most likely from a typedef + continue; + } search_index.push(IndexItem { ty: item.type_(), name: item.name.clone().unwrap(), @@ -592,19 +595,25 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { let mut lastpathid = 0usize; for item in search_index { - item.parent_idx = item.parent.map(|nodeid| { - if nodeid_to_pathid.contains_key(&nodeid) { - *nodeid_to_pathid.get(&nodeid).unwrap() - } else { - let pathid = lastpathid; - nodeid_to_pathid.insert(nodeid, pathid); - lastpathid += 1; + item.parent_idx = match item.parent { + Some(nodeid) => { + Some(if nodeid_to_pathid.contains_key(&nodeid) { + *nodeid_to_pathid.get(&nodeid).expect("no pathid") + } else { + let pathid = lastpathid; + nodeid_to_pathid.insert(nodeid, pathid); + lastpathid += 1; - let &(ref fqp, short) = paths.get(&nodeid).unwrap(); - crate_paths.push((short, fqp.last().unwrap().clone())); - pathid + if let Some(&(ref fqp, short)) = paths.get(&nodeid) { + crate_paths.push((short, fqp.last().expect("no fqp").clone())); + } else { + continue + } + pathid + }) } - }); + None => None, + }; // Omit the parent path if it is same to that of the prior item. if lastpath == item.path { @@ -639,7 +648,7 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { items: crate_items, paths: crate_paths, }) - .unwrap() + .expect("failed serde conversion") ) } From fd4a88f3098ab1b20267716102d49c8a43d151d8 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 14:41:46 +0100 Subject: [PATCH 02/19] Add test for typedef deref --- src/test/rustdoc/deref-typedef.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) create mode 100644 src/test/rustdoc/deref-typedef.rs diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs new file mode 100644 index 0000000000000..b2dc20a5030e7 --- /dev/null +++ b/src/test/rustdoc/deref-typedef.rs @@ -0,0 +1,19 @@ +#![crate_name = "foo"] + +// @has 'foo/struct.Bar.html' +// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' +// @has '-' '//*[@class="impl-items"]//*[@id="method.happy"]' 'pub fn happy(&self)' +// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.happy"]' 'happy' +pub struct FooA; +pub type FooB = FooA; + +impl FooA { + pub fn happy(&self) {} +} + +pub struct Bar; +impl std::ops::Deref for Bar { + type Target = FooB; + fn deref(&self) -> &FooB { unimplemented!() } +} From 81a5b94ac60cc1a9c8d365d8c6166c148279276c Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 10 Jan 2020 14:46:28 +0100 Subject: [PATCH 03/19] formatting --- src/librustdoc/clean/inline.rs | 8 +++----- src/librustdoc/clean/mod.rs | 18 ++--------------- src/librustdoc/html/render.rs | 20 ++++++++----------- src/librustdoc/html/render/cache.rs | 31 ++++++++++++++--------------- 4 files changed, 28 insertions(+), 49 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index fc75bf35b250d..e54e716e042fe 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -284,11 +284,9 @@ fn build_type_alias_type(cx: &DocContext<'_>, did: DefId) -> Option pub fn build_ty(cx: &DocContext, did: DefId) -> Option { match cx.tcx.def_kind(did)? { - DefKind::Struct | - DefKind::Union | - DefKind::Enum | - DefKind::Const | - DefKind::Static => Some(cx.tcx.type_of(did).clean(cx)), + DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::Const | DefKind::Static => { + Some(cx.tcx.type_of(did).clean(cx)) + } DefKind::TyAlias => build_type_alias_type(cx, did), _ => None, } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0cc4c55f49be8..027975a6d3288 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1124,14 +1124,7 @@ impl Clean for hir::ImplItem<'_> { hir::ImplItemKind::TyAlias(ref ty) => { let type_ = ty.clean(cx); let item_type = type_.def_id().and_then(|did| inline::build_ty(cx, did)); - TypedefItem( - Typedef { - type_, - generics: Generics::default(), - item_type, - }, - true, - ) + TypedefItem(Typedef { type_, generics: Generics::default(), item_type }, true) } hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem( OpaqueTy { bounds: bounds.clean(cx), generics: Generics::default() }, @@ -2011,14 +2004,7 @@ impl Clean for doctree::Typedef<'_> { visibility: self.vis.clean(cx), stability: cx.stability(self.id).clean(cx), deprecation: cx.deprecation(self.id).clean(cx), - inner: TypedefItem( - Typedef { - type_, - generics: self.gen.clean(cx), - item_type, - }, - false, - ), + inner: TypedefItem(Typedef { type_, generics: self.gen.clean(cx), item_type }, false), } } } diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 69e268f3f80c1..86d59a0cccd9a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -3474,12 +3474,10 @@ fn render_deref_methods( .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => { - Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), - }) - } + clean::TypedefItem(ref t, true) => Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }), _ => None, }) .next() @@ -4133,12 +4131,10 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .items .iter() .filter_map(|item| match item.inner { - clean::TypedefItem(ref t, true) => { - Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), - }) - } + clean::TypedefItem(ref t, true) => Some(match *t { + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), + _ => (&t.type_, &t.type_), + }), _ => None, }) .next() diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index cdfd6b3073adf..fd9c47d0c4a44 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -574,7 +574,8 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { // has since been learned. for &(did, ref item) in orphan_impl_items { if let Some(&(ref fqp, _)) = paths.get(&did) { - if item.name.is_none() { // this is most likely from a typedef + if item.name.is_none() { + // this is most likely from a typedef continue; } search_index.push(IndexItem { @@ -596,22 +597,20 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { for item in search_index { item.parent_idx = match item.parent { - Some(nodeid) => { - Some(if nodeid_to_pathid.contains_key(&nodeid) { - *nodeid_to_pathid.get(&nodeid).expect("no pathid") - } else { - let pathid = lastpathid; - nodeid_to_pathid.insert(nodeid, pathid); - lastpathid += 1; + Some(nodeid) => Some(if nodeid_to_pathid.contains_key(&nodeid) { + *nodeid_to_pathid.get(&nodeid).expect("no pathid") + } else { + let pathid = lastpathid; + nodeid_to_pathid.insert(nodeid, pathid); + lastpathid += 1; - if let Some(&(ref fqp, short)) = paths.get(&nodeid) { - crate_paths.push((short, fqp.last().expect("no fqp").clone())); - } else { - continue - } - pathid - }) - } + if let Some(&(ref fqp, short)) = paths.get(&nodeid) { + crate_paths.push((short, fqp.last().expect("no fqp").clone())); + } else { + continue; + } + pathid + }), None => None, }; From 6e791464bcabc3d64b8fd5de6f2217c67d81a8b1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 13:56:11 +0100 Subject: [PATCH 04/19] remove unneeded code from cache.rs --- src/librustdoc/html/render/cache.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/src/librustdoc/html/render/cache.rs b/src/librustdoc/html/render/cache.rs index fd9c47d0c4a44..f1f83acdda59e 100644 --- a/src/librustdoc/html/render/cache.rs +++ b/src/librustdoc/html/render/cache.rs @@ -574,10 +574,6 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { // has since been learned. for &(did, ref item) in orphan_impl_items { if let Some(&(ref fqp, _)) = paths.get(&did) { - if item.name.is_none() { - // this is most likely from a typedef - continue; - } search_index.push(IndexItem { ty: item.type_(), name: item.name.clone().unwrap(), @@ -596,23 +592,19 @@ fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String { let mut lastpathid = 0usize; for item in search_index { - item.parent_idx = match item.parent { - Some(nodeid) => Some(if nodeid_to_pathid.contains_key(&nodeid) { + item.parent_idx = item.parent.map(|nodeid| { + if nodeid_to_pathid.contains_key(&nodeid) { *nodeid_to_pathid.get(&nodeid).expect("no pathid") } else { let pathid = lastpathid; nodeid_to_pathid.insert(nodeid, pathid); lastpathid += 1; - if let Some(&(ref fqp, short)) = paths.get(&nodeid) { - crate_paths.push((short, fqp.last().expect("no fqp").clone())); - } else { - continue; - } + let &(ref fqp, short) = paths.get(&nodeid).unwrap(); + crate_paths.push((short, fqp.last().unwrap().clone())); pathid - }), - None => None, - }; + } + }); // Omit the parent path if it is same to that of the prior item. if lastpath == item.path { From e6ad49aa67b7e6e0d9c5bc4bd68f44a009f91595 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 15:07:27 +0100 Subject: [PATCH 05/19] Include type alias implementations --- src/librustdoc/html/render.rs | 53 +++++++++++++++++++++-------------- 1 file changed, 32 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 86d59a0cccd9a..aafc7a8a10ff6 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2595,7 +2595,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) } // If there are methods directly on this trait object, render them here. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All); + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All); let mut synthetic_types = Vec::new(); @@ -2942,7 +2942,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct } } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) { @@ -2988,7 +2988,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) document(w, cx, field); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { @@ -3130,7 +3130,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { render_stability_since(w, variant, it); } } - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn render_attribute(attr: &ast::MetaItem) -> Option { @@ -3344,7 +3344,7 @@ fn render_assoc_items( cx: &Context, containing_item: &clean::Item, it: DefId, - what: AssocItemRender<'_>, + what: &AssocItemRender<'_>, ) { let c = &cx.cache; let v = match c.impls.get(&it) { @@ -3377,7 +3377,7 @@ fn render_assoc_items( trait_.print(), type_.print() ); - RenderMode::ForDeref { mut_: deref_mut_ } + RenderMode::ForDeref { mut_: *deref_mut_ } } }; for i in &non_trait { @@ -3461,6 +3461,19 @@ fn render_assoc_items( } } +fn get_def_id(real_target: &clean::Type, cx: &Context) -> Option { + if let Some(did) = real_target.def_id() { + return Some(did); + } else { + if let Some(prim) = real_target.primitive_type() { + if let Some(&did) = cx.cache.primitive_locations.get(&prim) { + return Some(did); + } + } + } + None +} + fn render_deref_methods( w: &mut Buffer, cx: &Context, @@ -3475,23 +3488,21 @@ fn render_deref_methods( .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), + clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, Some(type_)), + _ => (&t.type_, None), }), _ => None, }) .next() .expect("Expected associated type binding"); + let did = get_def_id(&target, cx); let what = AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; - if let Some(did) = real_target.def_id() { - render_assoc_items(w, cx, container_item, did, what) - } else { - if let Some(prim) = real_target.primitive_type() { - if let Some(&did) = cx.cache.primitive_locations.get(&prim) { - render_assoc_items(w, cx, container_item, did, what); - } - } + if let Some(did) = did { + render_assoc_items(w, cx, container_item, did, &what); + } + if let Some(did) = real_target.and_then(|x| get_def_id(x, cx)) { + render_assoc_items(w, cx, container_item, did, &what); } } @@ -3873,7 +3884,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Opa // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::TraitAlias) { @@ -3894,7 +3905,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::T // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef) { @@ -3915,7 +3926,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { @@ -3930,7 +3941,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { @@ -4602,7 +4613,7 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) } fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) { From d755238172ead0c619ac404487615534abc51ef1 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 18:52:04 +0100 Subject: [PATCH 06/19] Simplify deref impls for type aliases --- src/librustdoc/clean/mod.rs | 31 +++++++++++++++-- src/librustdoc/html/render.rs | 63 +++++++++++++++-------------------- 2 files changed, 55 insertions(+), 39 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 027975a6d3288..ae15b458fbaea 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2105,7 +2105,7 @@ impl Clean> for doctree::Impl<'_> { build_deref_target_impls(cx, &items, &mut ret); } - let provided = trait_ + let provided: FxHashSet = trait_ .def_id() .map(|did| { cx.tcx @@ -2116,6 +2116,33 @@ impl Clean> for doctree::Impl<'_> { }) .unwrap_or_default(); + let for_ = self.for_.clean(cx); + let type_alias = for_.def_id().and_then(|did| match cx.tcx.def_kind(did) { + Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)), + _ => None, + }); + if let Some(type_alias) = type_alias { + ret.push(Item { + name: None, + attrs: self.attrs.clean(cx), + source: self.whence.clean(cx), + def_id, + visibility: self.vis.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), + inner: ImplItem(Impl { + unsafety: self.unsafety, + generics: self.generics.clean(cx), + provided_trait_methods: provided.clone(), + trait_: trait_.clone(), + for_: type_alias, + items: items.clone(), + polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), + synthetic: false, + blanket_impl: None, + }), + }); + } ret.push(Item { name: None, attrs: self.attrs.clean(cx), @@ -2129,7 +2156,7 @@ impl Clean> for doctree::Impl<'_> { generics: self.generics.clean(cx), provided_trait_methods: provided, trait_, - for_: self.for_.clean(cx), + for_, items, polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), synthetic: false, diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index aafc7a8a10ff6..aaacae045b903 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -2595,7 +2595,7 @@ fn item_trait(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Trait) } // If there are methods directly on this trait object, render them here. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All); + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All); let mut synthetic_types = Vec::new(); @@ -2942,7 +2942,7 @@ fn item_struct(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Struct } } } - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) { @@ -2988,7 +2988,7 @@ fn item_union(w: &mut Buffer, cx: &Context, it: &clean::Item, s: &clean::Union) document(w, cx, field); } } - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { @@ -3130,7 +3130,7 @@ fn item_enum(w: &mut Buffer, cx: &Context, it: &clean::Item, e: &clean::Enum) { render_stability_since(w, variant, it); } } - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn render_attribute(attr: &ast::MetaItem) -> Option { @@ -3344,7 +3344,7 @@ fn render_assoc_items( cx: &Context, containing_item: &clean::Item, it: DefId, - what: &AssocItemRender<'_>, + what: AssocItemRender<'_>, ) { let c = &cx.cache; let v = match c.impls.get(&it) { @@ -3377,7 +3377,7 @@ fn render_assoc_items( trait_.print(), type_.print() ); - RenderMode::ForDeref { mut_: *deref_mut_ } + RenderMode::ForDeref { mut_: deref_mut_ } } }; for i in &non_trait { @@ -3461,19 +3461,6 @@ fn render_assoc_items( } } -fn get_def_id(real_target: &clean::Type, cx: &Context) -> Option { - if let Some(did) = real_target.def_id() { - return Some(did); - } else { - if let Some(prim) = real_target.primitive_type() { - if let Some(&did) = cx.cache.primitive_locations.get(&prim) { - return Some(did); - } - } - } - None -} - fn render_deref_methods( w: &mut Buffer, cx: &Context, @@ -3488,21 +3475,23 @@ fn render_deref_methods( .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, Some(type_)), - _ => (&t.type_, None), + clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), + _ => (&t.type_, &t.type_), }), _ => None, }) .next() .expect("Expected associated type binding"); - let did = get_def_id(&target, cx); let what = - AssocItemRender::DerefFor { trait_: deref_type, type_: target, deref_mut_: deref_mut }; - if let Some(did) = did { - render_assoc_items(w, cx, container_item, did, &what); - } - if let Some(did) = real_target.and_then(|x| get_def_id(x, cx)) { - render_assoc_items(w, cx, container_item, did, &what); + AssocItemRender::DerefFor { trait_: deref_type, type_: real_target, deref_mut_: deref_mut }; + if let Some(did) = target.def_id() { + render_assoc_items(w, cx, container_item, did, what); + } else { + if let Some(prim) = target.primitive_type() { + if let Some(&did) = cx.cache.primitive_locations.get(&prim) { + render_assoc_items(w, cx, container_item, did, what); + } + } } } @@ -3884,7 +3873,7 @@ fn item_opaque_ty(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Opa // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::TraitAlias) { @@ -3905,7 +3894,7 @@ fn item_trait_alias(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::T // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typedef) { @@ -3926,7 +3915,7 @@ fn item_typedef(w: &mut Buffer, cx: &Context, it: &clean::Item, t: &clean::Typed // won't be visible anywhere in the docs. It would be nice to also show // associated items from the aliased type (see discussion in #32077), but // we need #14072 to make sense of the generics. - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { @@ -3941,7 +3930,7 @@ fn item_foreign_type(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn print_sidebar(cx: &Context, it: &clean::Item, buffer: &mut Buffer) { @@ -4137,20 +4126,20 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some((target, real_target)) = impl_ + if let Some(target) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => (&t.type_, type_), - _ => (&t.type_, &t.type_), + clean::Typedef { item_type: Some(ref type_), .. } => type_, + _ => &t.type_, }), _ => None, }) .next() { - let inner_impl = real_target + let inner_impl = target .def_id() .or(target .primitive_type() @@ -4613,7 +4602,7 @@ fn item_proc_macro(w: &mut Buffer, cx: &Context, it: &clean::Item, m: &clean::Pr fn item_primitive(w: &mut Buffer, cx: &Context, it: &clean::Item) { document(w, cx, it); - render_assoc_items(w, cx, it, it.def_id, &AssocItemRender::All) + render_assoc_items(w, cx, it, it.def_id, AssocItemRender::All) } fn item_keyword(w: &mut Buffer, cx: &Context, it: &clean::Item) { From 8a9b951f578a1389507c7251b5c75258ac215bf9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 15 Jan 2020 21:34:15 +0100 Subject: [PATCH 07/19] Fix rendering on sidebar and update tests --- src/librustdoc/html/render.rs | 8 ++++---- src/test/rustdoc/deref-typedef.rs | 28 +++++++++++++++++++++------- 2 files changed, 25 insertions(+), 11 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index aaacae045b903..9406803825350 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -4126,14 +4126,14 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { .filter(|i| i.inner_impl().trait_.is_some()) .find(|i| i.inner_impl().trait_.def_id() == c.deref_trait_did) { - if let Some(target) = impl_ + if let Some((target, real_target)) = impl_ .inner_impl() .items .iter() .filter_map(|item| match item.inner { clean::TypedefItem(ref t, true) => Some(match *t { - clean::Typedef { item_type: Some(ref type_), .. } => type_, - _ => &t.type_, + clean::Typedef { item_type: Some(ref type_), .. } => (type_, &t.type_), + _ => (&t.type_, &t.type_), }), _ => None, }) @@ -4153,7 +4153,7 @@ fn sidebar_assoc_items(it: &clean::Item) -> String { "{:#}", impl_.inner_impl().trait_.as_ref().unwrap().print() )), - Escape(&format!("{:#}", target.print())) + Escape(&format!("{:#}", real_target.print())) )); out.push_str(""); let mut ret = impls diff --git a/src/test/rustdoc/deref-typedef.rs b/src/test/rustdoc/deref-typedef.rs index b2dc20a5030e7..770f8d7289c3b 100644 --- a/src/test/rustdoc/deref-typedef.rs +++ b/src/test/rustdoc/deref-typedef.rs @@ -1,19 +1,33 @@ #![crate_name = "foo"] // @has 'foo/struct.Bar.html' -// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' -// @has '-' '//*[@class="impl-items"]//*[@id="method.happy"]' 'pub fn happy(&self)' -// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref' -// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.happy"]' 'happy' +// @has '-' '//*[@id="deref-methods"]' 'Methods from Deref' +// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_a"]' 'pub fn foo_a(&self)' +// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_b"]' 'pub fn foo_b(&self)' +// @has '-' '//*[@class="impl-items"]//*[@id="method.foo_c"]' 'pub fn foo_c(&self)' +// @has '-' '//*[@class="sidebar-title"]' 'Methods from Deref' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_a"]' 'foo_a' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_b"]' 'foo_b' +// @has '-' '//*[@class="sidebar-links"]/a[@href="#method.foo_c"]' 'foo_c' + pub struct FooA; pub type FooB = FooA; +pub type FooC = FooB; impl FooA { - pub fn happy(&self) {} + pub fn foo_a(&self) {} +} + +impl FooB { + pub fn foo_b(&self) {} +} + +impl FooC { + pub fn foo_c(&self) {} } pub struct Bar; impl std::ops::Deref for Bar { - type Target = FooB; - fn deref(&self) -> &FooB { unimplemented!() } + type Target = FooC; + fn deref(&self) -> &Self::Target { unimplemented!() } } From ea64a3394312d65c95c7e74e7b8fa7e454685113 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tomasz=20Mi=C4=85sko?= Date: Thu, 16 Jan 2020 00:00:00 +0000 Subject: [PATCH 08/19] Update sanitizer tests * Move tests from src/test/run-make-fulldeps to src/test/ui. * Fix memory sanitizer test to detect the intended issue rather than an unrelated one caused by the use of an uninstrumented std. --- .../sanitizer-address/Makefile | 30 ------------- .../sanitizer-address/overflow.rs | 4 -- .../sanitizer-invalid-target/Makefile | 5 --- .../sanitizer-invalid-target/hello.rs | 3 -- .../run-make-fulldeps/sanitizer-leak/Makefile | 7 --- .../sanitizer-memory/Makefile | 11 ----- .../sanitizer-memory/maybeuninit.rs | 8 ---- .../sanitizer-memory/uninit.rs | 7 --- src/test/ui/sanitizer-address.rs | 21 +++++++++ .../leak.rs => ui/sanitizer-leak.rs} | 8 ++++ src/test/ui/sanitizer-memory.rs | 44 +++++++++++++++++++ src/test/ui/sanitizer-unsupported-target.rs | 7 +++ .../ui/sanitizer-unsupported-target.stderr | 4 ++ 13 files changed, 84 insertions(+), 75 deletions(-) delete mode 100644 src/test/run-make-fulldeps/sanitizer-address/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-address/overflow.rs delete mode 100644 src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs delete mode 100644 src/test/run-make-fulldeps/sanitizer-leak/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-memory/Makefile delete mode 100644 src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs delete mode 100644 src/test/run-make-fulldeps/sanitizer-memory/uninit.rs create mode 100644 src/test/ui/sanitizer-address.rs rename src/test/{run-make-fulldeps/sanitizer-leak/leak.rs => ui/sanitizer-leak.rs} (62%) create mode 100644 src/test/ui/sanitizer-memory.rs create mode 100644 src/test/ui/sanitizer-unsupported-target.rs create mode 100644 src/test/ui/sanitizer-unsupported-target.stderr diff --git a/src/test/run-make-fulldeps/sanitizer-address/Makefile b/src/test/run-make-fulldeps/sanitizer-address/Makefile deleted file mode 100644 index 7f5e9049b2f77..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-address/Makefile +++ /dev/null @@ -1,30 +0,0 @@ -# needs-sanitizer-support - --include ../tools.mk - -LOG := $(TMPDIR)/log.txt - -# NOTE the address sanitizer only supports x86_64 linux and macOS - -ifeq ($(TARGET),x86_64-apple-darwin) -EXTRA_RUSTFLAG=-C rpath -else -ifeq ($(TARGET),x86_64-unknown-linux-gnu) - -# Apparently there are very specific Linux kernels, notably the one that's -# currently on Travis CI, which contain a buggy commit that triggers failures in -# the ASan implementation, detailed at google/sanitizers#837. As noted in -# google/sanitizers#856 the "fix" is to avoid using PIE binaries, so we pass a -# different relocation model to avoid generating a PIE binary. Once Travis is no -# longer running kernel 4.4.0-93 we can remove this and pass an empty set of -# flags again. -EXTRA_RUSTFLAG=-C relocation-model=dynamic-no-pic -endif -endif - -all: - $(RUSTC) -g -Z sanitizer=address -Z print-link-args $(EXTRA_RUSTFLAG) overflow.rs | $(CGREP) rustc_rt.asan - # Verify that stack buffer overflow is detected: - $(TMPDIR)/overflow 2>&1 | $(CGREP) stack-buffer-overflow - # Verify that variable name is included in address sanitizer report: - $(TMPDIR)/overflow 2>&1 | $(CGREP) "'xs'" diff --git a/src/test/run-make-fulldeps/sanitizer-address/overflow.rs b/src/test/run-make-fulldeps/sanitizer-address/overflow.rs deleted file mode 100644 index b997a74cc3eb4..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-address/overflow.rs +++ /dev/null @@ -1,4 +0,0 @@ -fn main() { - let xs = [0, 1, 2, 3]; - let _y = unsafe { *xs.as_ptr().offset(4) }; -} diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile b/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile deleted file mode 100644 index 2a23f0fe3d4ef..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-invalid-target/Makefile +++ /dev/null @@ -1,5 +0,0 @@ --include ../tools.mk - -all: - $(RUSTC) -Z sanitizer=leak --target i686-unknown-linux-gnu hello.rs 2>&1 | \ - $(CGREP) 'LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target' diff --git a/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs b/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs deleted file mode 100644 index d3dd5ed03d954..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-invalid-target/hello.rs +++ /dev/null @@ -1,3 +0,0 @@ -#![feature(no_core)] -#![no_core] -#![no_main] diff --git a/src/test/run-make-fulldeps/sanitizer-leak/Makefile b/src/test/run-make-fulldeps/sanitizer-leak/Makefile deleted file mode 100644 index da370335ca918..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-leak/Makefile +++ /dev/null @@ -1,7 +0,0 @@ --include ../tools.mk - -# needs-sanitizer-support - -all: - $(RUSTC) -O -Z sanitizer=leak -Z print-link-args leak.rs | $(CGREP) rustc_rt.lsan - $(TMPDIR)/leak 2>&1 | $(CGREP) 'detected memory leaks' diff --git a/src/test/run-make-fulldeps/sanitizer-memory/Makefile b/src/test/run-make-fulldeps/sanitizer-memory/Makefile deleted file mode 100644 index 8bc9df1b4baeb..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-memory/Makefile +++ /dev/null @@ -1,11 +0,0 @@ --include ../tools.mk - -# needs-sanitizer-support -# only-linux -# only-x86_64 - -all: - $(RUSTC) -g -Z sanitizer=memory -Z print-link-args uninit.rs | $(CGREP) rustc_rt.msan - $(TMPDIR)/uninit 2>&1 | $(CGREP) use-of-uninitialized-value - $(RUSTC) -g -Z sanitizer=memory -Z print-link-args maybeuninit.rs | $(CGREP) rustc_rt.msan - $(TMPDIR)/maybeuninit 2>&1 | $(CGREP) use-of-uninitialized-value diff --git a/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs deleted file mode 100644 index a9ae85f57639e..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-memory/maybeuninit.rs +++ /dev/null @@ -1,8 +0,0 @@ -use std::mem::MaybeUninit; - -fn main() { - // This is technically not sound -- but we're literally trying to test - // that the sanitizer catches this, so I guess "intentionally unsound"? - let xs: [u8; 4] = unsafe { MaybeUninit::uninit().assume_init() }; - let y = xs[0] + xs[1]; -} diff --git a/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs b/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs deleted file mode 100644 index eae52508f6585..0000000000000 --- a/src/test/run-make-fulldeps/sanitizer-memory/uninit.rs +++ /dev/null @@ -1,7 +0,0 @@ -fn main() { - // This is technically not sound -- but we're literally trying to test - // that the sanitizer catches this, so I guess "intentionally unsound"? - #[allow(deprecated)] - let xs: [u8; 4] = unsafe { std::mem::uninitialized() }; - let y = xs[0] + xs[1]; -} diff --git a/src/test/ui/sanitizer-address.rs b/src/test/ui/sanitizer-address.rs new file mode 100644 index 0000000000000..d27a30a2dc55f --- /dev/null +++ b/src/test/ui/sanitizer-address.rs @@ -0,0 +1,21 @@ +// needs-sanitizer-support +// only-x86_64 +// +// compile-flags: -Z sanitizer=address -O +// +// run-fail +// error-pattern: AddressSanitizer: stack-buffer-overflow +// error-pattern: 'xs' <== Memory access at offset + +#![feature(test)] + +use std::hint::black_box; +use std::mem; + +fn main() { + let xs = [0, 1, 2, 3]; + // Avoid optimizing everything out. + let xs = black_box(xs.as_ptr()); + let code = unsafe { *xs.offset(4) }; + std::process::exit(code); +} diff --git a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs b/src/test/ui/sanitizer-leak.rs similarity index 62% rename from src/test/run-make-fulldeps/sanitizer-leak/leak.rs rename to src/test/ui/sanitizer-leak.rs index fb0a917dd98b6..5c2f2cb4e868b 100644 --- a/src/test/run-make-fulldeps/sanitizer-leak/leak.rs +++ b/src/test/ui/sanitizer-leak.rs @@ -1,3 +1,11 @@ +// needs-sanitizer-support +// only-x86_64 +// +// compile-flags: -Z sanitizer=leak -O +// +// run-fail +// error-pattern: LeakSanitizer: detected memory leaks + #![feature(test)] use std::hint::black_box; diff --git a/src/test/ui/sanitizer-memory.rs b/src/test/ui/sanitizer-memory.rs new file mode 100644 index 0000000000000..3e1cf4509a31f --- /dev/null +++ b/src/test/ui/sanitizer-memory.rs @@ -0,0 +1,44 @@ +// needs-sanitizer-support +// only-linux +// only-x86_64 +// +// compile-flags: -Z sanitizer=memory -Zsanitizer-memory-track-origins -O +// +// run-fail +// error-pattern: MemorySanitizer: use-of-uninitialized-value +// error-pattern: Uninitialized value was created by an allocation +// error-pattern: in the stack frame of function 'random' +// +// This test case intentionally limits the usage of the std, +// since it will be linked with an uninstrumented version of it. + +#![feature(core_intrinsics)] +#![feature(start)] +#![feature(test)] + +use std::hint::black_box; +use std::mem::MaybeUninit; + +#[inline(never)] +#[no_mangle] +fn random() -> [isize; 32] { + let r = unsafe { MaybeUninit::uninit().assume_init() }; + // Avoid optimizing everything out. + black_box(r) +} + +#[inline(never)] +#[no_mangle] +fn xor(a: &[isize]) -> isize { + let mut s = 0; + for i in 0..a.len() { + s = s ^ a[i]; + } + s +} + +#[start] +fn main(_: isize, _: *const *const u8) -> isize { + let r = random(); + xor(&r) +} diff --git a/src/test/ui/sanitizer-unsupported-target.rs b/src/test/ui/sanitizer-unsupported-target.rs new file mode 100644 index 0000000000000..444333c3f01e2 --- /dev/null +++ b/src/test/ui/sanitizer-unsupported-target.rs @@ -0,0 +1,7 @@ +// ignore-tidy-linelength +// compile-flags: -Z sanitizer=leak --target i686-unknown-linux-gnu +// error-pattern: error: LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target + +#![feature(no_core)] +#![no_core] +#![no_main] diff --git a/src/test/ui/sanitizer-unsupported-target.stderr b/src/test/ui/sanitizer-unsupported-target.stderr new file mode 100644 index 0000000000000..38be58dd4b365 --- /dev/null +++ b/src/test/ui/sanitizer-unsupported-target.stderr @@ -0,0 +1,4 @@ +error: LeakSanitizer only works with the `x86_64-unknown-linux-gnu` or `x86_64-apple-darwin` target + +error: aborting due to previous error + From 25a8f9473f29e732838b6d88394dd80fe645b7f6 Mon Sep 17 00:00:00 2001 From: jumbatm <30644300+jumbatm@users.noreply.github.com> Date: Sat, 23 Nov 2019 14:52:40 +1000 Subject: [PATCH 09/19] Don't warn about snake case for field puns that don't introduce a new name. --- src/librustc_lint/nonstandard_style.rs | 15 ++++++++- ...62-no-snake-case-warning-for-field-puns.rs | 29 +++++++++++++++++ ...o-snake-case-warning-for-field-puns.stderr | 32 +++++++++++++++++++ 3 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs create mode 100644 src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr diff --git a/src/librustc_lint/nonstandard_style.rs b/src/librustc_lint/nonstandard_style.rs index a2b7884241ff7..394da4a5bb0c1 100644 --- a/src/librustc_lint/nonstandard_style.rs +++ b/src/librustc_lint/nonstandard_style.rs @@ -350,7 +350,20 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for NonSnakeCase { } fn check_pat(&mut self, cx: &LateContext<'_, '_>, p: &hir::Pat<'_>) { - if let &PatKind::Binding(_, _, ident, _) = &p.kind { + if let &PatKind::Binding(_, hid, ident, _) = &p.kind { + if let hir::Node::Pat(parent_pat) = cx.tcx.hir().get(cx.tcx.hir().get_parent_node(hid)) + { + if let PatKind::Struct(_, field_pats, _) = &parent_pat.kind { + for field in field_pats.iter() { + if field.ident != ident { + // Only check if a new name has been introduced, to avoid warning + // on both the struct definition and this pattern. + self.check_snake_case(cx, "variable", &ident); + } + } + return; + } + } self.check_snake_case(cx, "variable", &ident); } } diff --git a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs new file mode 100644 index 0000000000000..c2b81959f2cb8 --- /dev/null +++ b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.rs @@ -0,0 +1,29 @@ +#![deny(non_snake_case)] +#![allow(unused_variables)] +#![allow(dead_code)] + +enum Foo { + Bad { + lowerCamelCaseName: bool, + //~^ ERROR structure field `lowerCamelCaseName` should have a snake case name + }, + Good { + snake_case_name: bool, + }, +} + +fn main() { + let b = Foo::Bad { lowerCamelCaseName: true }; + + match b { + Foo::Bad { lowerCamelCaseName } => {} + Foo::Good { snake_case_name: lowerCamelCaseBinding } => { } + //~^ ERROR variable `lowerCamelCaseBinding` should have a snake case name + } + + if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { } + //~^ ERROR variable `anotherLowerCamelCaseBinding` should have a snake case name + + if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { } + //~^ ERROR variable `yetAnotherLowerCamelCaseBinding` should have a snake case name +} diff --git a/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr new file mode 100644 index 0000000000000..68956f21e8f1b --- /dev/null +++ b/src/test/ui/lint/issue-66362-no-snake-case-warning-for-field-puns.stderr @@ -0,0 +1,32 @@ +error: structure field `lowerCamelCaseName` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:7:9 + | +LL | lowerCamelCaseName: bool, + | ^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_name` + | +note: lint level defined here + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:1:9 + | +LL | #![deny(non_snake_case)] + | ^^^^^^^^^^^^^^ + +error: variable `lowerCamelCaseBinding` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:20:38 + | +LL | Foo::Good { snake_case_name: lowerCamelCaseBinding } => { } + | ^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `lower_camel_case_binding` + +error: variable `anotherLowerCamelCaseBinding` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:24:41 + | +LL | if let Foo::Good { snake_case_name: anotherLowerCamelCaseBinding } = b { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `another_lower_camel_case_binding` + +error: variable `yetAnotherLowerCamelCaseBinding` should have a snake case name + --> $DIR/issue-66362-no-snake-case-warning-for-field-puns.rs:27:43 + | +LL | if let Foo::Bad { lowerCamelCaseName: yetAnotherLowerCamelCaseBinding } = b { } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: convert the identifier to snake case: `yet_another_lower_camel_case_binding` + +error: aborting due to 4 previous errors + From 3094c3792bb0bffbaaa0688d02c970054c353d1f Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 21:36:39 +0100 Subject: [PATCH 10/19] Improve code readability --- src/librustdoc/clean/mod.rs | 36 ++++++++++-------------------------- 1 file changed, 10 insertions(+), 26 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index ae15b458fbaea..0e9f363bec3f3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2121,8 +2121,8 @@ impl Clean> for doctree::Impl<'_> { Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)), _ => None, }); - if let Some(type_alias) = type_alias { - ret.push(Item { + let make_item = |trait_: Option, for_: Type, items: Vec| { + Item { name: None, attrs: self.attrs.clean(cx), source: self.whence.clean(cx), @@ -2134,35 +2134,19 @@ impl Clean> for doctree::Impl<'_> { unsafety: self.unsafety, generics: self.generics.clean(cx), provided_trait_methods: provided.clone(), - trait_: trait_.clone(), - for_: type_alias, - items: items.clone(), + trait_, + for_, + items, polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), synthetic: false, blanket_impl: None, }), - }); + } + }; + if let Some(type_alias) = type_alias { + ret.push(make_item(trait_.clone(), type_alias, items.clone())); } - ret.push(Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id, - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: ImplItem(Impl { - unsafety: self.unsafety, - generics: self.generics.clean(cx), - provided_trait_methods: provided, - trait_, - for_, - items, - polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), - synthetic: false, - blanket_impl: None, - }), - }); + ret.push(make_item(trait_, for_, items)); ret } } From 10a9ea4c2622544d52ecef47fea0404a7ce0ace4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 15 Jan 2020 09:57:06 -0800 Subject: [PATCH 11/19] Do not ICE on malformed suggestion spans --- src/librustc_errors/emitter.rs | 9 ++++++++- src/librustc_errors/lib.rs | 13 +++++++++++++ src/librustc_span/source_map.rs | 11 +++++++---- .../ui/consts/miri_unleashed/mutable_const2.stderr | 2 +- 4 files changed, 29 insertions(+), 6 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index 526b4e2971bef..e37496f729952 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1475,6 +1475,11 @@ impl EmitterWriter { Some(ref sm) => sm, None => return Ok(()), }; + if !suggestion.has_valid_spans(&**sm) { + // Suggestions coming from macros can have malformed spans. This is a heavy handed + // approach to avoid ICEs by ignoring the suggestion outright. + return Ok(()); + } let mut buffer = StyledBuffer::new(); @@ -1505,7 +1510,9 @@ impl EmitterWriter { let show_underline = !(parts.len() == 1 && parts[0].snippet.trim() == complete.trim()) && complete.lines().count() == 1; - let lines = sm.span_to_lines(parts[0].span).unwrap(); + let lines = sm + .span_to_lines(parts[0].span) + .expect("span_to_lines failed when emitting suggestion"); assert!(!lines.lines.is_empty()); diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index e24e8719133a9..889c84d6da132 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -10,6 +10,7 @@ pub use emitter::ColorConfig; +use log::debug; use Level::*; use emitter::{is_case_difference, Emitter, EmitterWriter}; @@ -143,6 +144,18 @@ pub struct SubstitutionPart { } impl CodeSuggestion { + /// Suggestions coming from macros can have malformed spans. This is a heavy handed approach + /// to avoid ICEs by ignoring the suggestion outright. + pub fn has_valid_spans(&self, cm: &SourceMap) -> bool { + !self.substitutions.iter().any(|subst| { + let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err()); + if invalid { + debug!("malformed span in suggestion: {:?}", subst); + } + invalid + }) + } + /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec, bool)> { diff --git a/src/librustc_span/source_map.rs b/src/librustc_span/source_map.rs index fb5fcf4a8303b..9c7c0f0c8b0ec 100644 --- a/src/librustc_span/source_map.rs +++ b/src/librustc_span/source_map.rs @@ -473,20 +473,23 @@ impl SourceMap { lo.line != hi.line } - pub fn span_to_lines(&self, sp: Span) -> FileLinesResult { - debug!("span_to_lines(sp={:?})", sp); - + pub fn is_valid_span(&self, sp: Span) -> Result<(Loc, Loc), SpanLinesError> { let lo = self.lookup_char_pos(sp.lo()); debug!("span_to_lines: lo={:?}", lo); let hi = self.lookup_char_pos(sp.hi()); debug!("span_to_lines: hi={:?}", hi); - if lo.file.start_pos != hi.file.start_pos { return Err(SpanLinesError::DistinctSources(DistinctSources { begin: (lo.file.name.clone(), lo.file.start_pos), end: (hi.file.name.clone(), hi.file.start_pos), })); } + Ok((lo, hi)) + } + + pub fn span_to_lines(&self, sp: Span) -> FileLinesResult { + debug!("span_to_lines(sp={:?})", sp); + let (lo, hi) = self.is_valid_span(sp)?; assert!(hi.line >= lo.line); let mut lines = Vec::with_capacity(hi.line - lo.line + 1); diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index 655c31763ef44..cc124058cfcb8 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:346:17 +thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:359:17 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic From 03240e1359f68bdddcdb236f3a89f9907b907449 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 16 Jan 2020 18:27:18 -0800 Subject: [PATCH 12/19] review comments --- src/librustc_errors/emitter.rs | 9 ++++---- src/librustc_errors/lib.rs | 21 ++++++++----------- .../miri_unleashed/mutable_const2.stderr | 2 +- 3 files changed, 15 insertions(+), 17 deletions(-) diff --git a/src/librustc_errors/emitter.rs b/src/librustc_errors/emitter.rs index e37496f729952..b0e0cb611afaf 100644 --- a/src/librustc_errors/emitter.rs +++ b/src/librustc_errors/emitter.rs @@ -1475,7 +1475,11 @@ impl EmitterWriter { Some(ref sm) => sm, None => return Ok(()), }; - if !suggestion.has_valid_spans(&**sm) { + + // Render the replacements for each suggestion + let suggestions = suggestion.splice_lines(&**sm); + + if suggestions.is_empty() { // Suggestions coming from macros can have malformed spans. This is a heavy handed // approach to avoid ICEs by ignoring the suggestion outright. return Ok(()); @@ -1497,9 +1501,6 @@ impl EmitterWriter { Some(Style::HeaderMsg), ); - // Render the replacements for each suggestion - let suggestions = suggestion.splice_lines(&**sm); - let mut row_num = 2; let mut notice_capitalization = false; for (complete, parts, only_capitalization) in suggestions.iter().take(MAX_SUGGESTIONS) { diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 889c84d6da132..827e9b831f32d 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -144,18 +144,6 @@ pub struct SubstitutionPart { } impl CodeSuggestion { - /// Suggestions coming from macros can have malformed spans. This is a heavy handed approach - /// to avoid ICEs by ignoring the suggestion outright. - pub fn has_valid_spans(&self, cm: &SourceMap) -> bool { - !self.substitutions.iter().any(|subst| { - let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err()); - if invalid { - debug!("malformed span in suggestion: {:?}", subst); - } - invalid - }) - } - /// Returns the assembled code suggestions, whether they should be shown with an underline /// and whether the substitution only differs in capitalization. pub fn splice_lines(&self, cm: &SourceMap) -> Vec<(String, Vec, bool)> { @@ -187,6 +175,15 @@ impl CodeSuggestion { self.substitutions .iter() + .filter(|subst| { + // Suggestions coming from macros can have malformed spans. This is a heavy + // handed approach to avoid ICEs by ignoring the suggestion outright. + let invalid = subst.parts.iter().any(|item| cm.is_valid_span(item.span).is_err()); + if invalid { + debug!("splice_lines: suggestion contains an invalid span: {:?}", subst); + } + !invalid + }) .cloned() .map(|mut substitution| { // Assumption: all spans are in the same file, and all spans diff --git a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr index cc124058cfcb8..0d7fb845a40ee 100644 --- a/src/test/ui/consts/miri_unleashed/mutable_const2.stderr +++ b/src/test/ui/consts/miri_unleashed/mutable_const2.stderr @@ -10,7 +10,7 @@ error: internal compiler error: mutable allocation in constant LL | const MUTABLE_BEHIND_RAW: *mut i32 = &UnsafeCell::new(42) as *const _ as *mut _; | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:359:17 +thread 'rustc' panicked at 'no errors encountered even though `delay_span_bug` issued', src/librustc_errors/lib.rs:356:17 note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace error: internal compiler error: unexpected panic From cdc828e7f92c5835db4188f27cbdb7170d32c94e Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Fri, 17 Jan 2020 17:09:05 +0100 Subject: [PATCH 13/19] Stop treating `FalseEdges` and `FalseUnwind` as having semantic value for const eval --- .../transform/qualify_min_const_fn.rs | 19 ++++++------------- 1 file changed, 6 insertions(+), 13 deletions(-) diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 7034556740849..d927553c72e8b 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -309,7 +309,11 @@ fn check_terminator( ) -> McfResult { let span = terminator.source_info.span; match &terminator.kind { - TerminatorKind::Goto { .. } | TerminatorKind::Return | TerminatorKind::Resume => Ok(()), + TerminatorKind::FalseEdges { .. } + | TerminatorKind::FalseUnwind { .. } + | TerminatorKind::Goto { .. } + | TerminatorKind::Return + | TerminatorKind::Resume => Ok(()), TerminatorKind::Drop { location, .. } => check_place(tcx, location, span, def_id, body), TerminatorKind::DropAndReplace { location, value, .. } => { @@ -317,13 +321,10 @@ fn check_terminator( check_operand(tcx, value, span, def_id, body) } - TerminatorKind::FalseEdges { .. } | TerminatorKind::SwitchInt { .. } - if !feature_allowed(tcx, def_id, sym::const_if_match) => - { + TerminatorKind::SwitchInt { .. } if !feature_allowed(tcx, def_id, sym::const_if_match) => { Err((span, "loops and conditional expressions are not stable in const fn".into())) } - TerminatorKind::FalseEdges { .. } => Ok(()), TerminatorKind::SwitchInt { discr, switch_ty: _, values: _, targets: _ } => { check_operand(tcx, discr, span, def_id, body) } @@ -367,13 +368,5 @@ fn check_terminator( TerminatorKind::Assert { cond, expected: _, msg: _, target: _, cleanup: _ } => { check_operand(tcx, cond, span, def_id, body) } - - TerminatorKind::FalseUnwind { .. } if feature_allowed(tcx, def_id, sym::const_loop) => { - Ok(()) - } - - TerminatorKind::FalseUnwind { .. } => { - Err((span, "loops are not allowed in const fn".into())) - } } } From a91f77ca26f65e566b93a0f086a894e60ec7c257 Mon Sep 17 00:00:00 2001 From: varkor Date: Fri, 17 Jan 2020 14:21:14 +0000 Subject: [PATCH 14/19] Add regression test for integer literals in generic arguments in where clauses --- ...eger-literal-generic-arg-in-where-clause.rs | 18 ++++++++++++++++++ ...-literal-generic-arg-in-where-clause.stderr | 8 ++++++++ 2 files changed, 26 insertions(+) create mode 100644 src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs create mode 100644 src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr diff --git a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs new file mode 100644 index 0000000000000..30fbfda112c55 --- /dev/null +++ b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.rs @@ -0,0 +1,18 @@ +// check-pass + +#![feature(const_generics)] +//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash + +fn takes_closure_of_array_3(f: F) where F: Fn([i32; 3]) { + f([1, 2, 3]); +} + +fn takes_closure_of_array_3_apit(f: impl Fn([i32; 3])) { + f([1, 2, 3]); +} + +fn returns_closure_of_array_3() -> impl Fn([i32; 3]) { + |_| {} +} + +fn main() {} diff --git a/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr new file mode 100644 index 0000000000000..7f37f3e2791ec --- /dev/null +++ b/src/test/ui/const-generics/integer-literal-generic-arg-in-where-clause.stderr @@ -0,0 +1,8 @@ +warning: the feature `const_generics` is incomplete and may cause the compiler to crash + --> $DIR/integer-literal-generic-arg-in-where-clause.rs:3:12 + | +LL | #![feature(const_generics)] + | ^^^^^^^^^^^^^^ + | + = note: `#[warn(incomplete_features)]` on by default + From 9c6c2f16f00ed6f24866d2d4927b49d79b453a23 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 16 Jan 2020 14:35:37 +0100 Subject: [PATCH 15/19] Clean up E0198 explanation --- src/librustc_error_codes/error_codes/E0198.md | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0198.md b/src/librustc_error_codes/error_codes/E0198.md index 6504d60dbd1d5..687214a205096 100644 --- a/src/librustc_error_codes/error_codes/E0198.md +++ b/src/librustc_error_codes/error_codes/E0198.md @@ -1,17 +1,18 @@ -A negative implementation is one that excludes a type from implementing a -particular trait. Not being able to use a trait is always a safe operation, -so negative implementations are always safe and never need to be marked as -unsafe. +A negative implementation was marked as unsafe. -```compile_fail -#![feature(optin_builtin_traits)] +Erroneous code example: +```compile_fail struct Foo; -// unsafe is unnecessary -unsafe impl !Clone for Foo { } +unsafe impl !Clone for Foo { } // error! ``` +A negative implementation is one that excludes a type from implementing a +particular trait. Not being able to use a trait is always a safe operation, +so negative implementations are always safe and never need to be marked as +unsafe. + This will compile: ```ignore (ignore auto_trait future compatibility warning) From 482dc77dee59dd44448973758980806bd63aa5a3 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 17 Jan 2020 19:51:07 +0100 Subject: [PATCH 16/19] formatting --- src/librustdoc/clean/mod.rs | 40 ++++++++++++++++++------------------- 1 file changed, 19 insertions(+), 21 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 0e9f363bec3f3..20a5a6c54984d 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2121,27 +2121,25 @@ impl Clean> for doctree::Impl<'_> { Some(DefKind::TyAlias) => Some(cx.tcx.type_of(did).clean(cx)), _ => None, }); - let make_item = |trait_: Option, for_: Type, items: Vec| { - Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id, - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: ImplItem(Impl { - unsafety: self.unsafety, - generics: self.generics.clean(cx), - provided_trait_methods: provided.clone(), - trait_, - for_, - items, - polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), - synthetic: false, - blanket_impl: None, - }), - } + let make_item = |trait_: Option, for_: Type, items: Vec| Item { + name: None, + attrs: self.attrs.clean(cx), + source: self.whence.clean(cx), + def_id, + visibility: self.vis.clean(cx), + stability: cx.stability(self.id).clean(cx), + deprecation: cx.deprecation(self.id).clean(cx), + inner: ImplItem(Impl { + unsafety: self.unsafety, + generics: self.generics.clean(cx), + provided_trait_methods: provided.clone(), + trait_, + for_, + items, + polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), + synthetic: false, + blanket_impl: None, + }), }; if let Some(type_alias) = type_alias { ret.push(make_item(trait_.clone(), type_alias, items.clone())); From e8a4b9319cbf5b3f56b3cdd8ad11e86ff7168345 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 17 Jan 2020 19:54:07 +0100 Subject: [PATCH 17/19] Clean up E0199 explanation --- src/librustc_error_codes/error_codes/E0199.md | 21 +++++++++++++------ 1 file changed, 15 insertions(+), 6 deletions(-) diff --git a/src/librustc_error_codes/error_codes/E0199.md b/src/librustc_error_codes/error_codes/E0199.md index d0c12dc6f1755..88130e8e5e596 100644 --- a/src/librustc_error_codes/error_codes/E0199.md +++ b/src/librustc_error_codes/error_codes/E0199.md @@ -1,14 +1,23 @@ +A trait implementation was marked as unsafe while the trait is safe. + +Erroneous code example: + +```compile_fail,E0199 +struct Foo; + +trait Bar { } + +unsafe impl Bar for Foo { } // error! +``` + Safe traits should not have unsafe implementations, therefore marking an implementation for a safe trait unsafe will cause a compiler error. Removing -the unsafe marker on the trait noted in the error will resolve this problem. +the unsafe marker on the trait noted in the error will resolve this problem: -```compile_fail,E0199 +``` struct Foo; trait Bar { } -// this won't compile because Bar is safe -unsafe impl Bar for Foo { } -// this will compile -impl Bar for Foo { } +impl Bar for Foo { } // ok! ``` From d461e6d6cbd0c716f8b7e951285507451611df59 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Mon, 13 Jan 2020 20:30:20 -0800 Subject: [PATCH 18/19] Use named fields for `ast::ItemKind::Impl` --- src/librustc/hir/map/mod.rs | 2 +- src/librustc_ast_lowering/item.rs | 21 ++++++++-------- src/librustc_ast_passes/ast_validation.rs | 24 +++++++++++++++---- src/librustc_ast_passes/feature_gate.rs | 2 +- .../deriving/generic/mod.rs | 16 ++++++------- src/librustc_builtin_macros/deriving/mod.rs | 16 ++++++------- src/librustc_lint/builtin.rs | 2 +- src/librustc_lint/internal.rs | 2 +- src/librustc_parse/parser/item.rs | 20 ++++++++-------- src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/def_collector.rs | 2 +- src/librustc_resolve/late.rs | 16 ++++++------- src/librustc_save_analysis/dump_visitor.rs | 4 ++-- src/librustc_save_analysis/lib.rs | 12 +++++----- src/librustc_save_analysis/sig.rs | 14 +++++------ src/libsyntax/ast.rs | 23 ++++++++++-------- src/libsyntax/mut_visit.rs | 14 ++++++++--- src/libsyntax/print/pprust.rs | 16 ++++++------- src/libsyntax/visit.rs | 16 +++++++++---- 19 files changed, 130 insertions(+), 94 deletions(-) diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 46c5ee272d235..8b4f0c6bde2b5 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -821,7 +821,7 @@ impl<'hir> Map<'hir> { | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Trait(..) - | ItemKind::Impl(..) => true, + | ItemKind::Impl { .. } => true, _ => false, }, Node::ForeignItem(fi) => match fi.kind { diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index beb53a19ac4ff..648c4f7e46aad 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -67,14 +67,15 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { if let Some(hir_id) = item_hir_id { self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { let this = &mut ItemLowerer { lctx: this }; - if let ItemKind::Impl(.., ref opt_trait_ref, _, _) = item.kind { - if opt_trait_ref.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) { + if let ItemKind::Impl { ref of_trait, .. } = item.kind { + if of_trait.as_ref().map(|tr| tr.constness.is_some()).unwrap_or(false) { + this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); this.lctx .diagnostic() .span_err(item.span, "const trait impls are not yet implemented"); } - this.with_trait_impl_ref(opt_trait_ref, |this| visit::walk_item(this, item)); + this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); } else { visit::walk_item(this, item); } @@ -173,7 +174,7 @@ impl<'hir> LoweringContext<'_, 'hir> { vec } ItemKind::MacroDef(..) => SmallVec::new(), - ItemKind::Fn(..) | ItemKind::Impl(.., None, _, _) => smallvec![i.id], + ItemKind::Fn(..) | ItemKind::Impl { of_trait: None, .. } => smallvec![i.id], ItemKind::Static(ref ty, ..) => { let mut ids = smallvec![i.id]; if self.sess.features_untracked().impl_trait_in_bindings { @@ -361,15 +362,15 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_generics(generics, ImplTraitContext::disallowed()), ) } - ItemKind::Impl( + ItemKind::Impl { unsafety, polarity, defaultness, - ref ast_generics, - ref trait_ref, - ref ty, - ref impl_items, - ) => { + generics: ref ast_generics, + of_trait: ref trait_ref, + self_ty: ref ty, + items: ref impl_items, + } => { let def_id = self.resolver.definitions().local_def_id(id); // Lower the "impl header" first. This ordering is important diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index c915b7ba21692..23701459025ae 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -612,9 +612,17 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } match item.kind { - ItemKind::Impl(unsafety, polarity, _, _, Some(..), ref ty, ref impl_items) => { + ItemKind::Impl { + unsafety, + polarity, + defaultness: _, + generics: _, + of_trait: Some(_), + ref self_ty, + ref items, + } => { self.invalid_visibility(&item.vis, None); - if let TyKind::Err = ty.kind { + if let TyKind::Err = self_ty.kind { self.err_handler() .struct_span_err(item.span, "`impl Trait for .. {}` is an obsolete syntax") .help("use `auto trait Trait {}` instead") @@ -629,7 +637,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> { ) .emit(); } - for impl_item in impl_items { + for impl_item in items { self.invalid_visibility(&impl_item.vis, None); if let AssocItemKind::Fn(ref sig, _) = impl_item.kind { self.check_trait_fn_not_const(sig.header.constness); @@ -637,7 +645,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { } } } - ItemKind::Impl(unsafety, polarity, defaultness, _, None, _, _) => { + ItemKind::Impl { + unsafety, + polarity, + defaultness, + generics: _, + of_trait: None, + self_ty: _, + items: _, + } => { self.invalid_visibility( &item.vis, Some("place qualifiers on individual impl items instead"), diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index 1e4b1ae077762..71cd66ddef409 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -339,7 +339,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } } - ast::ItemKind::Impl(_, polarity, defaultness, ..) => { + ast::ItemKind::Impl { polarity, defaultness, .. } => { if polarity == ast::ImplPolarity::Negative { gate_feature_post!( &self, diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index 9226f45816506..d346dbc8b4ee7 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -705,15 +705,15 @@ impl<'a> TraitDef<'a> { self.span, Ident::invalid(), a, - ast::ItemKind::Impl( + ast::ItemKind::Impl { unsafety, - ast::ImplPolarity::Positive, - ast::Defaultness::Final, - trait_generics, - opt_trait_ref, - self_type, - methods.into_iter().chain(associated_types).collect(), - ), + polarity: ast::ImplPolarity::Positive, + defaultness: ast::Defaultness::Final, + generics: trait_generics, + of_trait: opt_trait_ref, + self_ty: self_type, + items: methods.into_iter().chain(associated_types).collect(), + }, ) } diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs index 4d83a6635ab17..9aa7623dc9f77 100644 --- a/src/librustc_builtin_macros/deriving/mod.rs +++ b/src/librustc_builtin_macros/deriving/mod.rs @@ -156,15 +156,15 @@ fn inject_impl_of_structural_trait( span, ast::Ident::invalid(), attrs, - ItemKind::Impl( - ast::Unsafety::Normal, - ast::ImplPolarity::Positive, - ast::Defaultness::Final, + ItemKind::Impl { + unsafety: ast::Unsafety::Normal, + polarity: ast::ImplPolarity::Positive, + defaultness: ast::Defaultness::Final, generics, - Some(trait_ref), - self_type, - Vec::new(), - ), + of_trait: Some(trait_ref), + self_ty: self_type, + items: Vec::new(), + }, ); push(Annotatable::Item(newitem)); diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index 6314c2b99539a..a15f69d7d51eb 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -251,7 +251,7 @@ impl EarlyLintPass for UnsafeCode { self.report_unsafe(cx, it.span, "declaration of an `unsafe` trait") } - ast::ItemKind::Impl(ast::Unsafety::Unsafe, ..) => { + ast::ItemKind::Impl { unsafety: ast::Unsafety::Unsafe, .. } => { self.report_unsafe(cx, it.span, "implementation of an `unsafe` trait") } diff --git a/src/librustc_lint/internal.rs b/src/librustc_lint/internal.rs index 5a5aedc2e9715..91aeccbb5e334 100644 --- a/src/librustc_lint/internal.rs +++ b/src/librustc_lint/internal.rs @@ -221,7 +221,7 @@ declare_lint_pass!(LintPassImpl => [LINT_PASS_IMPL_WITHOUT_MACRO]); impl EarlyLintPass for LintPassImpl { fn check_item(&mut self, cx: &EarlyContext<'_>, item: &Item) { - if let ItemKind::Impl(_, _, _, _, Some(lint_pass), _, _) = &item.kind { + if let ItemKind::Impl { of_trait: Some(lint_pass), .. } = &item.kind { if let Some(last) = lint_pass.path.segments.last() { if last.ident.name == sym::LintPass { let expn_data = lint_pass.path.span.ctxt().outer_expn_data(); diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index d4756dff49a9d..1921a6c850689 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -634,15 +634,15 @@ impl<'a> Parser<'a> { let constness = constness.map(|c| c.node); let trait_ref = TraitRef { path, constness, ref_id: ty_first.id }; - ItemKind::Impl( + ItemKind::Impl { unsafety, polarity, defaultness, generics, - Some(trait_ref), - ty_second, - impl_items, - ) + of_trait: Some(trait_ref), + self_ty: ty_second, + items: impl_items, + } } None => { // Reject `impl const Type {}` here @@ -653,15 +653,15 @@ impl<'a> Parser<'a> { } // impl Type - ItemKind::Impl( + ItemKind::Impl { unsafety, polarity, defaultness, generics, - None, - ty_first, - impl_items, - ) + of_trait: None, + self_ty: ty_first, + items: impl_items, + } } }; diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index e8ed64a18702d..40a89ef067458 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -815,7 +815,7 @@ impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { } // These items do not add names to modules. - ItemKind::Impl(..) | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {} + ItemKind::Impl { .. } | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) => {} ItemKind::MacroDef(..) | ItemKind::Mac(_) => unreachable!(), } diff --git a/src/librustc_resolve/def_collector.rs b/src/librustc_resolve/def_collector.rs index f564ea644bdc1..696ba0e994c7d 100644 --- a/src/librustc_resolve/def_collector.rs +++ b/src/librustc_resolve/def_collector.rs @@ -104,7 +104,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> { // Pick the def data. This need not be unique, but the more // information we encapsulate into, the better let def_data = match &i.kind { - ItemKind::Impl(..) => DefPathData::Impl, + ItemKind::Impl { .. } => DefPathData::Impl, ItemKind::Mod(..) if i.ident.name == kw::Invalid => { return visit::walk_item(self, i); } diff --git a/src/librustc_resolve/late.rs b/src/librustc_resolve/late.rs index defca4944bcd8..08cd9c4d1d53a 100644 --- a/src/librustc_resolve/late.rs +++ b/src/librustc_resolve/late.rs @@ -797,14 +797,14 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> { self.resolve_adt(item, generics); } - ItemKind::Impl(.., ref generics, ref opt_trait_ref, ref self_type, ref impl_items) => { - self.resolve_implementation( - generics, - opt_trait_ref, - &self_type, - item.id, - impl_items, - ) + ItemKind::Impl { + ref generics, + ref of_trait, + ref self_ty, + items: ref impl_items, + .. + } => { + self.resolve_implementation(generics, of_trait, &self_ty, item.id, impl_items); } ItemKind::Trait(.., ref generics, ref bounds, ref trait_items) => { diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 2f2ba560fa20a..d252fc542c325 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -1300,8 +1300,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> { self.process_struct(item, def, ty_params) } Enum(ref def, ref ty_params) => self.process_enum(item, def, ty_params), - Impl(.., ref ty_params, ref trait_ref, ref typ, ref impl_items) => { - self.process_impl(item, ty_params, trait_ref, &typ, impl_items) + Impl { ref generics, ref of_trait, ref self_ty, ref items, .. } => { + self.process_impl(item, generics, of_trait, &self_ty, items) } Trait(_, _, ref generics, ref trait_refs, ref methods) => { self.process_trait(item, generics, trait_refs, methods) diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index c3221d925bc3b..5412533fce7d8 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -305,8 +305,8 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { attributes: lower_attributes(item.attrs.clone(), self), })) } - ast::ItemKind::Impl(.., ref trait_ref, ref typ, ref impls) => { - if let ast::TyKind::Path(None, ref path) = typ.kind { + ast::ItemKind::Impl { ref of_trait, ref self_ty, ref items, .. } => { + if let ast::TyKind::Path(None, ref path) = self_ty.kind { // Common case impl for a struct or something basic. if generated_code(path.span) { return None; @@ -317,14 +317,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { let impl_id = self.next_impl_id(); let span = self.span_from_span(sub_span); - let type_data = self.lookup_def_id(typ.id); + let type_data = self.lookup_def_id(self_ty.id); type_data.map(|type_data| { Data::RelationData( Relation { kind: RelationKind::Impl { id: impl_id }, span: span.clone(), from: id_from_def_id(type_data), - to: trait_ref + to: of_trait .as_ref() .and_then(|t| self.lookup_def_id(t.ref_id)) .map(id_from_def_id) @@ -332,14 +332,14 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { }, Impl { id: impl_id, - kind: match *trait_ref { + kind: match *of_trait { Some(_) => ImplKind::Direct, None => ImplKind::Inherent, }, span: span, value: String::new(), parent: None, - children: impls + children: items .iter() .map(|i| id_from_node_id(i.id, self)) .collect(), diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index e7b86cfba4f7d..779d3f55018d5 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -482,15 +482,15 @@ impl Sig for ast::Item { Ok(sig) } - ast::ItemKind::Impl( + ast::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref opt_trait, - ref ty, - _, - ) => { + ref of_trait, + ref self_ty, + items: _, + } => { let mut text = String::new(); if let ast::Defaultness::Default = defaultness { text.push_str("default "); @@ -505,7 +505,7 @@ impl Sig for ast::Item { text.push(' '); - let trait_sig = if let Some(ref t) = *opt_trait { + let trait_sig = if let Some(ref t) = *of_trait { if polarity == ast::ImplPolarity::Negative { text.push('!'); } @@ -517,7 +517,7 @@ impl Sig for ast::Item { text_sig(String::new()) }; - let ty_sig = ty.make(offset + text.len(), id, scx)?; + let ty_sig = self_ty.make(offset + text.len(), id, scx)?; text.push_str(&ty_sig.text); text.push_str(" {}"); diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 331eb109ec0b4..a5a4eb1583bed 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2614,15 +2614,18 @@ pub enum ItemKind { /// An implementation. /// /// E.g., `impl Foo { .. }` or `impl Trait for Foo { .. }`. - Impl( - Unsafety, - ImplPolarity, - Defaultness, - Generics, - Option, // (optional) trait this impl implements - P, // self - Vec, - ), + Impl { + unsafety: Unsafety, + polarity: ImplPolarity, + defaultness: Defaultness, + generics: Generics, + + /// The trait being implemented, if any. + of_trait: Option, + + self_ty: P, + items: Vec, + }, /// A macro invocation. /// /// E.g., `foo!(..)`. @@ -2649,7 +2652,7 @@ impl ItemKind { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl(..) => "item", + ItemKind::Mac(..) | ItemKind::MacroDef(..) | ItemKind::Impl { .. } => "item", } } } diff --git a/src/libsyntax/mut_visit.rs b/src/libsyntax/mut_visit.rs index 58d4e46111b83..750d054e8a0f2 100644 --- a/src/libsyntax/mut_visit.rs +++ b/src/libsyntax/mut_visit.rs @@ -918,10 +918,18 @@ pub fn noop_visit_item_kind(kind: &mut ItemKind, vis: &mut T) { vis.visit_variant_data(variant_data); vis.visit_generics(generics); } - ItemKind::Impl(_unsafety, _polarity, _defaultness, generics, trait_ref, ty, items) => { + ItemKind::Impl { + unsafety: _, + polarity: _, + defaultness: _, + generics, + of_trait, + self_ty, + items, + } => { vis.visit_generics(generics); - visit_opt(trait_ref, |trait_ref| vis.visit_trait_ref(trait_ref)); - vis.visit_ty(ty); + visit_opt(of_trait, |trait_ref| vis.visit_trait_ref(trait_ref)); + vis.visit_ty(self_ty); items.flat_map_in_place(|item| vis.flat_map_impl_item(item)); } ItemKind::Trait(_is_auto, _unsafety, generics, bounds, items) => { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 11c8cb8ef7500..bc67980c454c0 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -1226,15 +1226,15 @@ impl<'a> State<'a> { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident, item.span, true); } - ast::ItemKind::Impl( + ast::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref opt_trait, - ref ty, - ref impl_items, - ) => { + ref of_trait, + ref self_ty, + ref items, + } => { self.head(""); self.print_visibility(&item.vis); self.print_defaultness(defaultness); @@ -1250,19 +1250,19 @@ impl<'a> State<'a> { self.s.word("!"); } - if let Some(ref t) = *opt_trait { + if let Some(ref t) = *of_trait { self.print_trait_ref(t); self.s.space(); self.word_space("for"); } - self.print_type(ty); + self.print_type(self_ty); self.print_where_clause(&generics.where_clause); self.s.space(); self.bopen(); self.print_inner_attributes(&item.attrs); - for impl_item in impl_items { + for impl_item in items { self.print_assoc_item(impl_item); } self.bclose(item.span); diff --git a/src/libsyntax/visit.rs b/src/libsyntax/visit.rs index 3c2ebacbc4e34..d03a9dfc16758 100644 --- a/src/libsyntax/visit.rs +++ b/src/libsyntax/visit.rs @@ -308,11 +308,19 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) { visitor.visit_generics(generics); visitor.visit_enum_def(enum_definition, generics, item.id, item.span) } - ItemKind::Impl(_, _, _, ref generics, ref opt_trait_reference, ref typ, ref impl_items) => { + ItemKind::Impl { + unsafety: _, + polarity: _, + defaultness: _, + ref generics, + ref of_trait, + ref self_ty, + ref items, + } => { visitor.visit_generics(generics); - walk_list!(visitor, visit_trait_ref, opt_trait_reference); - visitor.visit_ty(typ); - walk_list!(visitor, visit_impl_item, impl_items); + walk_list!(visitor, visit_trait_ref, of_trait); + visitor.visit_ty(self_ty); + walk_list!(visitor, visit_impl_item, items); } ItemKind::Struct(ref struct_definition, ref generics) | ItemKind::Union(ref struct_definition, ref generics) => { From 4743995ed3f7a60e5e0b66eb6a095483883d8c90 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Fri, 17 Jan 2020 16:14:29 -0800 Subject: [PATCH 19/19] Use named fields for `hir::ItemKind::Impl` --- src/librustc/hir/check_attr.rs | 4 +- src/librustc/hir/map/mod.rs | 6 +-- src/librustc/infer/error_reporting/mod.rs | 2 +- .../traits/error_reporting/suggestions.rs | 5 +-- src/librustc/traits/util.rs | 2 +- src/librustc/traits/wf.rs | 8 ++-- src/librustc_ast_lowering/item.rs | 14 +++--- src/librustc_hir/hir.rs | 25 ++++++----- src/librustc_hir/intravisit.rs | 16 +++++-- src/librustc_hir/print.rs | 16 +++---- .../persist/dirty_clean.rs | 2 +- src/librustc_lint/builtin.rs | 4 +- src/librustc_metadata/rmeta/encoder.rs | 14 +++--- src/librustc_mir/monomorphize/collector.rs | 6 +-- src/librustc_passes/dead.rs | 8 ++-- src/librustc_passes/reachable.rs | 10 ++--- src/librustc_passes/stability.rs | 10 ++--- src/librustc_privacy/lib.rs | 44 +++++++++---------- src/librustc_resolve/lifetimes.rs | 10 ++--- src/librustc_save_analysis/lib.rs | 4 +- src/librustc_traits/lowering/environment.rs | 4 +- src/librustc_ty/ty.rs | 8 ++-- src/librustc_typeck/check/mod.rs | 10 +---- src/librustc_typeck/check/wfcheck.rs | 6 +-- src/librustc_typeck/coherence/builtin.rs | 9 ++-- .../coherence/inherent_impls.rs | 2 +- src/librustc_typeck/coherence/orphan.rs | 4 +- src/librustc_typeck/coherence/unsafety.rs | 2 +- src/librustc_typeck/collect.rs | 36 +++++++-------- src/librustc_typeck/impl_wf_check.rs | 6 +-- src/librustdoc/clean/inline.rs | 8 ++-- src/librustdoc/test.rs | 4 +- src/librustdoc/visit_ast.rs | 18 ++++---- 33 files changed, 166 insertions(+), 161 deletions(-) diff --git a/src/librustc/hir/check_attr.rs b/src/librustc/hir/check_attr.rs index 5a99e7965538b..5a4d7ceea2734 100644 --- a/src/librustc/hir/check_attr.rs +++ b/src/librustc/hir/check_attr.rs @@ -112,7 +112,7 @@ impl Target { ItemKind::Union(..) => Target::Union, ItemKind::Trait(..) => Target::Trait, ItemKind::TraitAlias(..) => Target::TraitAlias, - ItemKind::Impl(..) => Target::Impl, + ItemKind::Impl { .. } => Target::Impl, } } @@ -144,7 +144,7 @@ impl Target { let parent_hir_id = tcx.hir().get_parent_item(impl_item.hir_id); let containing_item = tcx.hir().expect_item(parent_hir_id); let containing_impl_is_for_trait = match &containing_item.kind { - hir::ItemKind::Impl(_, _, _, _, tr, _, _) => tr.is_some(), + hir::ItemKind::Impl { ref of_trait, .. } => of_trait.is_some(), _ => bug!("parent of an ImplItem must be an Impl"), }; if containing_impl_is_for_trait { diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 8b4f0c6bde2b5..6d7f53133a666 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -341,7 +341,7 @@ impl<'hir> Map<'hir> { | ItemKind::Use(..) | ItemKind::ForeignMod(..) | ItemKind::GlobalAsm(..) - | ItemKind::Impl(..) => return None, + | ItemKind::Impl { .. } => return None, }, Node::ForeignItem(item) => match item.kind { ForeignItemKind::Fn(..) => DefKind::Fn, @@ -604,7 +604,7 @@ impl<'hir> Map<'hir> { | ItemKind::Union(_, ref generics) | ItemKind::Trait(_, _, ref generics, ..) | ItemKind::TraitAlias(ref generics, _) - | ItemKind::Impl(_, _, _, ref generics, ..) => Some(generics), + | ItemKind::Impl { ref generics, .. } => Some(generics), _ => None, }, _ => None, @@ -1332,7 +1332,7 @@ fn hir_id_to_string(map: &Map<'_>, id: HirId, include_id: bool) -> String { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "impl", + ItemKind::Impl { .. } => "impl", }; format!("{} {}{}", item_str, path_str(), id_str) } diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index febf4f21a6755..a2009461fa568 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -254,7 +254,7 @@ fn emit_msg_span( fn item_scope_tag(item: &hir::Item<'_>) -> &'static str { match item.kind { - hir::ItemKind::Impl(..) => "impl", + hir::ItemKind::Impl { .. } => "impl", hir::ItemKind::Struct(..) => "struct", hir::ItemKind::Union(..) => "union", hir::ItemKind::Enum(..) => "enum", diff --git a/src/librustc/traits/error_reporting/suggestions.rs b/src/librustc/traits/error_reporting/suggestions.rs index bf6891214ace1..c09fd3079731c 100644 --- a/src/librustc/traits/error_reporting/suggestions.rs +++ b/src/librustc/traits/error_reporting/suggestions.rs @@ -88,8 +88,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .. }) | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(_, _, _, generics, ..), - .. + kind: hir::ItemKind::Impl { generics, .. }, .. }) if projection.is_some() => { // Missing associated type bound. suggest_restriction(&generics, "the associated type", err); @@ -115,7 +114,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { .. }) | hir::Node::Item(hir::Item { - kind: hir::ItemKind::Impl(_, _, _, generics, ..), + kind: hir::ItemKind::Impl { generics, .. }, span, .. }) diff --git a/src/librustc/traits/util.rs b/src/librustc/traits/util.rs index 65fd809657bd0..f058a4d2df24a 100644 --- a/src/librustc/traits/util.rs +++ b/src/librustc/traits/util.rs @@ -651,7 +651,7 @@ pub fn impl_is_default(tcx: TyCtxt<'_>, node_item_def_id: DefId) -> bool { match tcx.hir().as_local_hir_id(node_item_def_id) { Some(hir_id) => { let item = tcx.hir().expect_item(hir_id); - if let hir::ItemKind::Impl(_, _, defaultness, ..) = item.kind { + if let hir::ItemKind::Impl { defaultness, .. } = item.kind { defaultness.is_default() } else { false diff --git a/src/librustc/traits/wf.rs b/src/librustc/traits/wf.rs index 2301395f557f1..869ba5315c1ae 100644 --- a/src/librustc/traits/wf.rs +++ b/src/librustc/traits/wf.rs @@ -229,9 +229,9 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // | // = note: expected type `u32` // found type `()` - if let Some(hir::ItemKind::Impl(.., impl_items)) = item.map(|i| &i.kind) { + if let Some(hir::ItemKind::Impl { items, .. }) = item.map(|i| &i.kind) { let trait_assoc_item = tcx.associated_item(proj.projection_def_id()); - if let Some(impl_item) = impl_items + if let Some(impl_item) = items .iter() .filter(|item| item.ident == trait_assoc_item.ident) .next() @@ -279,14 +279,14 @@ impl<'a, 'tcx> WfPredicates<'a, 'tcx> { // | ^^^^^^^^^^^^^^^^^^ the trait `Bar` is not implemented for `bool` if let ( ty::Projection(ty::ProjectionTy { item_def_id, .. }), - Some(hir::ItemKind::Impl(.., impl_items)), + Some(hir::ItemKind::Impl { items, .. }), ) = (&proj.skip_binder().self_ty().kind, item.map(|i| &i.kind)) { if let Some((impl_item, trait_assoc_item)) = trait_assoc_items .filter(|i| i.def_id == *item_def_id) .next() .and_then(|trait_assoc_item| { - impl_items + items .iter() .filter(|i| i.ident == trait_assoc_item.ident) .next() diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index 648c4f7e46aad..6da2d457f3c3b 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -119,7 +119,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let old_len = self.in_scope_lifetimes.len(); let parent_generics = match self.items.get(&parent_hir_id).unwrap().kind { - hir::ItemKind::Impl(_, _, _, ref generics, ..) + hir::ItemKind::Impl { ref generics, .. } | hir::ItemKind::Trait(_, _, ref generics, ..) => &generics.params[..], _ => &[], }; @@ -418,15 +418,15 @@ impl<'hir> LoweringContext<'_, 'hir> { ) }); - hir::ItemKind::Impl( + hir::ItemKind::Impl { unsafety, polarity, - self.lower_defaultness(defaultness, true /* [1] */), + defaultness: self.lower_defaultness(defaultness, true /* [1] */), generics, - trait_ref, - lowered_ty, - new_impl_items, - ) + of_trait: trait_ref, + self_ty: lowered_ty, + items: new_impl_items, + } } ItemKind::Trait(is_auto, unsafety, ref generics, ref bounds, ref items) => { let bounds = self.lower_param_bounds(bounds, ImplTraitContext::disallowed()); diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 5c1d600c837c4..1fef871b5140e 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -2436,15 +2436,18 @@ pub enum ItemKind<'hir> { TraitAlias(Generics<'hir>, GenericBounds<'hir>), /// An implementation, e.g., `impl Trait for Foo { .. }`. - Impl( - Unsafety, - ImplPolarity, - Defaultness, - Generics<'hir>, - Option>, // (optional) trait this impl implements - &'hir Ty<'hir>, // self - &'hir [ImplItemRef<'hir>], - ), + Impl { + unsafety: Unsafety, + polarity: ImplPolarity, + defaultness: Defaultness, + generics: Generics<'hir>, + + /// The trait being implemented, if any. + of_trait: Option>, + + self_ty: &'hir Ty<'hir>, + items: &'hir [ImplItemRef<'hir>], + }, } impl ItemKind<'_> { @@ -2465,7 +2468,7 @@ impl ItemKind<'_> { ItemKind::Union(..) => "union", ItemKind::Trait(..) => "trait", ItemKind::TraitAlias(..) => "trait alias", - ItemKind::Impl(..) => "impl", + ItemKind::Impl { .. } => "impl", } } @@ -2478,7 +2481,7 @@ impl ItemKind<'_> { | ItemKind::Struct(_, ref generics) | ItemKind::Union(_, ref generics) | ItemKind::Trait(_, _, ref generics, _, _) - | ItemKind::Impl(_, _, _, ref generics, _, _, _) => generics, + | ItemKind::Impl { ref generics, .. } => generics, _ => return None, }) } diff --git a/src/librustc_hir/intravisit.rs b/src/librustc_hir/intravisit.rs index 3dbc5253a9abf..1a73e41db9da5 100644 --- a/src/librustc_hir/intravisit.rs +++ b/src/librustc_hir/intravisit.rs @@ -566,12 +566,20 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item<'v>) { // `visit_enum_def()` takes care of visiting the `Item`'s `HirId`. visitor.visit_enum_def(enum_definition, generics, item.hir_id, item.span) } - ItemKind::Impl(.., ref generics, ref opt_trait_reference, ref typ, impl_item_refs) => { + ItemKind::Impl { + unsafety: _, + defaultness: _, + polarity: _, + ref generics, + ref of_trait, + ref self_ty, + items, + } => { visitor.visit_id(item.hir_id); visitor.visit_generics(generics); - walk_list!(visitor, visit_trait_ref, opt_trait_reference); - visitor.visit_ty(typ); - walk_list!(visitor, visit_impl_item_ref, impl_item_refs); + walk_list!(visitor, visit_trait_ref, of_trait); + visitor.visit_ty(self_ty); + walk_list!(visitor, visit_impl_item_ref, items); } ItemKind::Struct(ref struct_definition, ref generics) | ItemKind::Union(ref struct_definition, ref generics) => { diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index 759f423070aa0..6c7d419395317 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -627,15 +627,15 @@ impl<'a> State<'a> { self.head(visibility_qualified(&item.vis, "union")); self.print_struct(struct_def, generics, item.ident.name, item.span, true); } - hir::ItemKind::Impl( + hir::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref opt_trait, - ref ty, - impl_items, - ) => { + ref of_trait, + ref self_ty, + items, + } => { self.head(""); self.print_visibility(&item.vis); self.print_defaultness(defaultness); @@ -651,19 +651,19 @@ impl<'a> State<'a> { self.s.word("!"); } - if let Some(ref t) = opt_trait { + if let Some(ref t) = of_trait { self.print_trait_ref(t); self.s.space(); self.word_space("for"); } - self.print_type(&ty); + self.print_type(&self_ty); self.print_where_clause(&generics.where_clause); self.s.space(); self.bopen(); self.print_inner_attributes(&item.attrs); - for impl_item in impl_items { + for impl_item in items { self.ann.nested(self, Nested::ImplItem(impl_item.id)); } self.bclose(item.span); diff --git a/src/librustc_incremental/persist/dirty_clean.rs b/src/librustc_incremental/persist/dirty_clean.rs index ddfed53fa3349..c5e74868bda4a 100644 --- a/src/librustc_incremental/persist/dirty_clean.rs +++ b/src/librustc_incremental/persist/dirty_clean.rs @@ -315,7 +315,7 @@ impl DirtyCleanVisitor<'tcx> { //HirItem::Trait(..) => ("ItemTrait", LABELS_TRAIT), // An implementation, eg `impl Trait for Foo { .. }` - HirItem::Impl(..) => ("ItemKind::Impl", LABELS_IMPL), + HirItem::Impl { .. } => ("ItemKind::Impl", LABELS_IMPL), _ => self.tcx.sess.span_fatal( attr.span, diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index a15f69d7d51eb..c8d3d5f9c83d8 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -431,7 +431,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { "a trait" } hir::ItemKind::TyAlias(..) => "a type alias", - hir::ItemKind::Impl(.., Some(ref trait_ref), _, impl_item_refs) => { + hir::ItemKind::Impl { of_trait: Some(ref trait_ref), items, .. } => { // If the trait is private, add the impl items to `private_traits` so they don't get // reported for missing docs. let real_trait = trait_ref.path.res.def_id(); @@ -439,7 +439,7 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for MissingDoc { match cx.tcx.hir().find(hir_id) { Some(Node::Item(item)) => { if let hir::VisibilityKind::Inherited = item.vis.node { - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { self.private_traits.insert(impl_item_ref.id.hir_id); } } diff --git a/src/librustc_metadata/rmeta/encoder.rs b/src/librustc_metadata/rmeta/encoder.rs index 8ad92ce75a851..9d2bea28c8c2e 100644 --- a/src/librustc_metadata/rmeta/encoder.rs +++ b/src/librustc_metadata/rmeta/encoder.rs @@ -1073,7 +1073,7 @@ impl EncodeContext<'tcx> { ctor: None, }), adt_def.repr) } - hir::ItemKind::Impl(_, _, defaultness, ..) => { + hir::ItemKind::Impl { defaultness, .. } => { let trait_ref = self.tcx.impl_trait_ref(def_id); let polarity = self.tcx.impl_polarity(def_id); let parent = if let Some(trait_ref) = trait_ref { @@ -1149,7 +1149,7 @@ impl EncodeContext<'tcx> { }) ) } - hir::ItemKind::Impl(..) | hir::ItemKind::Trait(..) => { + hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) => { let associated_item_def_ids = self.tcx.associated_item_def_ids(def_id); record!(self.per_def.children[def_id] <- associated_item_def_ids.iter().map(|&def_id| { @@ -1172,13 +1172,13 @@ impl EncodeContext<'tcx> { | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) - | hir::ItemKind::Impl(..) => self.encode_item_type(def_id), + | hir::ItemKind::Impl { .. } => self.encode_item_type(def_id), _ => {} } if let hir::ItemKind::Fn(..) = item.kind { record!(self.per_def.fn_sig[def_id] <- tcx.fn_sig(def_id)); } - if let hir::ItemKind::Impl(..) = item.kind { + if let hir::ItemKind::Impl { .. } = item.kind { if let Some(trait_ref) = self.tcx.impl_trait_ref(def_id) { record!(self.per_def.impl_trait_ref[def_id] <- trait_ref); } @@ -1199,7 +1199,7 @@ impl EncodeContext<'tcx> { | hir::ItemKind::Enum(..) | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) - | hir::ItemKind::Impl(..) + | hir::ItemKind::Impl { .. } | hir::ItemKind::OpaqueTy(..) | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) => { @@ -1645,7 +1645,7 @@ impl EncodeContext<'tcx> { hir::ItemKind::Union(..) => { self.encode_fields(def_id); } - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { for &trait_item_def_id in self.tcx.associated_item_def_ids(def_id).iter() { self.encode_info_for_impl_item(trait_item_def_id); } @@ -1666,7 +1666,7 @@ struct ImplVisitor<'tcx> { impl<'tcx, 'v> ItemLikeVisitor<'v> for ImplVisitor<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { - if let hir::ItemKind::Impl(..) = item.kind { + if let hir::ItemKind::Impl { .. } = item.kind { let impl_id = self.tcx.hir().local_def_id(item.hir_id); if let Some(trait_ref) = self.tcx.impl_trait_ref(impl_id) { self.impls.entry(trait_ref.def_id).or_default().push(impl_id.index); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index 85377180bea46..f4611c32e0a32 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -954,7 +954,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> { // Nothing to do, just keep recursing. } - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { if self.mode == MonoItemCollectionMode::Eager { create_mono_items_for_default_impls(self.tcx, item, self.output); } @@ -1098,7 +1098,7 @@ fn create_mono_items_for_default_impls<'tcx>( output: &mut Vec>, ) { match item.kind { - hir::ItemKind::Impl(_, _, _, ref generics, .., ref impl_item_refs) => { + hir::ItemKind::Impl { ref generics, ref items, .. } => { for param in generics.params { match param.kind { hir::GenericParamKind::Lifetime { .. } => {} @@ -1119,7 +1119,7 @@ fn create_mono_items_for_default_impls<'tcx>( let param_env = ty::ParamEnv::reveal_all(); let trait_ref = tcx.normalize_erasing_regions(param_env, trait_ref); let overridden_methods: FxHashSet<_> = - impl_item_refs.iter().map(|iiref| iiref.ident.modern()).collect(); + items.iter().map(|iiref| iiref.ident.modern()).collect(); for method in tcx.provided_trait_methods(trait_ref.def_id) { if overridden_methods.contains(&method.ident.modern()) { continue; diff --git a/src/librustc_passes/dead.rs b/src/librustc_passes/dead.rs index f2778b2aa6bcd..2ff9d744f2c4d 100644 --- a/src/librustc_passes/dead.rs +++ b/src/librustc_passes/dead.rs @@ -405,10 +405,10 @@ impl<'v, 'k, 'tcx> ItemLikeVisitor<'v> for LifeSeeder<'k, 'tcx> { } } } - hir::ItemKind::Impl(.., ref opt_trait, _, impl_item_refs) => { - for impl_item_ref in impl_item_refs { + hir::ItemKind::Impl { ref of_trait, items, .. } => { + for impl_item_ref in items { let impl_item = self.krate.impl_item(impl_item_ref.id); - if opt_trait.is_some() + if of_trait.is_some() || has_allow_dead_code_or_lang_attr( self.tcx, impl_item.hir_id, @@ -586,7 +586,7 @@ impl Visitor<'tcx> for DeadVisitor<'tcx> { | hir::ItemKind::Struct(..) | hir::ItemKind::Union(..) | hir::ItemKind::Trait(..) - | hir::ItemKind::Impl(..) => { + | hir::ItemKind::Impl { .. } => { // FIXME(66095): Because item.span is annotated with things // like expansion data, and ident.span isn't, we use the // def_span method if it's part of a macro invocation diff --git a/src/librustc_passes/reachable.rs b/src/librustc_passes/reachable.rs index 5ce677f52cea6..667898046ac36 100644 --- a/src/librustc_passes/reachable.rs +++ b/src/librustc_passes/reachable.rs @@ -35,7 +35,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item<'_>, attrs: Codegen hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => { return true; } - hir::ItemKind::Impl(..) | hir::ItemKind::Fn(..) => { + hir::ItemKind::Impl { .. } | hir::ItemKind::Fn(..) => { let generics = tcx.generics_of(tcx.hir().local_def_id(item.hir_id)); generics.requires_monomorphization(tcx) } @@ -181,7 +181,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { // does too. let impl_hir_id = self.tcx.hir().as_local_hir_id(impl_did).unwrap(); match self.tcx.hir().expect_item(impl_hir_id).kind { - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { let generics = self.tcx.generics_of(impl_did); generics.requires_monomorphization(self.tcx) } @@ -266,7 +266,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { | hir::ItemKind::Static(..) | hir::ItemKind::Mod(..) | hir::ItemKind::ForeignMod(..) - | hir::ItemKind::Impl(..) + | hir::ItemKind::Impl { .. } | hir::ItemKind::Trait(..) | hir::ItemKind::TraitAlias(..) | hir::ItemKind::Struct(..) @@ -349,9 +349,9 @@ impl<'a, 'tcx> ItemLikeVisitor<'tcx> for CollectPrivateImplItemsVisitor<'a, 'tcx } // We need only trait impls here, not inherent impls, and only non-exported ones - if let hir::ItemKind::Impl(.., Some(ref trait_ref), _, ref impl_item_refs) = item.kind { + if let hir::ItemKind::Impl { of_trait: Some(ref trait_ref), ref items, .. } = item.kind { if !self.access_levels.is_reachable(item.hir_id) { - self.worklist.extend(impl_item_refs.iter().map(|ii_ref| ii_ref.id.hir_id)); + self.worklist.extend(items.iter().map(|ii_ref| ii_ref.id.hir_id)); let trait_def_id = match trait_ref.path.res { Res::Def(DefKind::Trait, def_id) => def_id, diff --git a/src/librustc_passes/stability.rs b/src/librustc_passes/stability.rs index 5ec7e73f873e0..b649f36f2fc58 100644 --- a/src/librustc_passes/stability.rs +++ b/src/librustc_passes/stability.rs @@ -219,11 +219,11 @@ impl<'a, 'tcx> Visitor<'tcx> for Annotator<'a, 'tcx> { // they don't have their own stability. They still can be annotated as unstable // and propagate this unstability to children, but this annotation is completely // optional. They inherit stability from their parents when unannotated. - hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => { + hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => { self.in_trait_impl = false; kind = AnnotationKind::Container; } - hir::ItemKind::Impl(.., Some(_), _, _) => { + hir::ItemKind::Impl { of_trait: Some(_), .. } => { self.in_trait_impl = true; } hir::ItemKind::Struct(ref sd, _) => { @@ -308,7 +308,7 @@ impl<'a, 'tcx> Visitor<'tcx> for MissingStabilityAnnotations<'a, 'tcx> { // they don't have their own stability. They still can be annotated as unstable // and propagate this unstability to children, but this annotation is completely // optional. They inherit stability from their parents when unannotated. - hir::ItemKind::Impl(.., None, _, _) | hir::ItemKind::ForeignMod(..) => {} + hir::ItemKind::Impl { of_trait: None, .. } | hir::ItemKind::ForeignMod(..) => {} _ => self.check_missing_stability(i.hir_id, i.span, i.kind.descriptive_variant()), } @@ -463,9 +463,9 @@ impl Visitor<'tcx> for Checker<'tcx> { // For implementations of traits, check the stability of each item // individually as it's possible to have a stable trait with unstable // items. - hir::ItemKind::Impl(.., Some(ref t), _, impl_item_refs) => { + hir::ItemKind::Impl { of_trait: Some(ref t), items, .. } => { if let Res::Def(DefKind::Trait, trait_did) = t.path.res { - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); let trait_item_def_id = self .tcx diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 70d4841ec244b..90a422a4dcf6c 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -255,8 +255,8 @@ fn def_id_visibility<'tcx>( Node::ImplItem(impl_item) => { match tcx.hir().get(tcx.hir().get_parent_item(hir_id)) { Node::Item(item) => match &item.kind { - hir::ItemKind::Impl(.., None, _, _) => &impl_item.vis, - hir::ItemKind::Impl(.., Some(trait_ref), _, _) => { + hir::ItemKind::Impl { of_trait: None, .. } => &impl_item.vis, + hir::ItemKind::Impl { of_trait: Some(trait_ref), .. } => { return def_id_visibility(tcx, trait_ref.path.res.def_id()); } kind => bug!("unexpected item kind: {:?}", kind), @@ -686,7 +686,7 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { let inherited_item_level = match item.kind { - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { Option::::of_impl(item.hir_id, self.tcx, &self.access_levels) } // Foreign modules inherit level from parents. @@ -730,9 +730,9 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } } } - hir::ItemKind::Impl(.., ref trait_ref, _, impl_item_refs) => { - for impl_item_ref in impl_item_refs { - if trait_ref.is_some() || impl_item_ref.vis.node.is_pub() { + hir::ItemKind::Impl { ref of_trait, items, .. } => { + for impl_item_ref in items { + if of_trait.is_some() || impl_item_ref.vis.node.is_pub() { self.update(impl_item_ref.id.hir_id, item_level); } } @@ -827,11 +827,11 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> { } } // Visit everything except for private impl items. - hir::ItemKind::Impl(.., impl_item_refs) => { + hir::ItemKind::Impl { items, .. } => { if item_level.is_some() { self.reach(item.hir_id, item_level).generics().predicates().ty().trait_ref(); - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item_level = self.get(impl_item_ref.id.hir_id); if impl_item_level.is_some() { self.reach(impl_item_ref.id.hir_id, impl_item_level) @@ -1510,7 +1510,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // (i.e., we could just return here to not check them at // all, or some worse estimation of whether an impl is // publicly visible). - hir::ItemKind::Impl(.., ref g, ref trait_ref, ref self_, impl_item_refs) => { + hir::ItemKind::Impl { generics: ref g, ref of_trait, ref self_ty, items, .. } => { // `impl [... for] Private` is never visible. let self_contains_private; // `impl [... for] Public<...>`, but not `impl [... for] @@ -1525,7 +1525,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { at_outer_type: true, outer_type_is_public_path: false, }; - visitor.visit_ty(&self_); + visitor.visit_ty(&self_ty); self_contains_private = visitor.contains_private; self_is_public_path = visitor.outer_type_is_public_path; } @@ -1533,7 +1533,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // Miscellaneous info about the impl: // `true` iff this is `impl Private for ...`. - let not_private_trait = trait_ref.as_ref().map_or( + let not_private_trait = of_trait.as_ref().map_or( true, // no trait counts as public trait |tr| { let did = tr.path.res.def_id(); @@ -1554,8 +1554,8 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { // directly because we might have `impl> ...`, // and we shouldn't warn about the generics if all the methods // are private (because `T` won't be visible externally). - let trait_or_some_public_method = trait_ref.is_some() - || impl_item_refs.iter().any(|impl_item_ref| { + let trait_or_some_public_method = of_trait.is_some() + || items.iter().any(|impl_item_ref| { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item.kind { hir::ImplItemKind::Const(..) | hir::ImplItemKind::Method(..) => { @@ -1570,9 +1570,9 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { if !self_contains_private && not_private_trait && trait_or_some_public_method { intravisit::walk_generics(self, g); - match *trait_ref { + match of_trait { None => { - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { // This is where we choose whether to walk down // further into the impl to check its items. We // should only walk into public items so that we @@ -1594,7 +1594,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } } } - Some(ref tr) => { + Some(tr) => { // Any private types in a trait impl fall into three // categories. // 1. mentioned in the trait definition @@ -1611,7 +1611,7 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { intravisit::walk_path(self, &tr.path); // Those in 3. are warned with this call. - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); if let hir::ImplItemKind::TyAlias(ref ty) = impl_item.kind { self.visit_ty(ty); @@ -1619,11 +1619,11 @@ impl<'a, 'tcx> Visitor<'tcx> for ObsoleteVisiblePrivateTypesVisitor<'a, 'tcx> { } } } - } else if trait_ref.is_none() && self_is_public_path { + } else if of_trait.is_none() && self_is_public_path { // `impl Public { ... }`. Any public static // methods will be visible as `Public::foo`. let mut found_pub_static = false; - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { if self.item_is_public(&impl_item_ref.id.hir_id, &impl_item_ref.vis) { let impl_item = self.tcx.hir().impl_item(impl_item_ref.id); match impl_item_ref.kind { @@ -1997,12 +1997,12 @@ impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> // Subitems of inherent impls have their own publicity. // A trait impl is public when both its type and its trait are public // Subitems of trait impls have inherited publicity. - hir::ItemKind::Impl(.., ref trait_ref, _, impl_item_refs) => { + hir::ItemKind::Impl { ref of_trait, items, .. } => { let impl_vis = ty::Visibility::of_impl(item.hir_id, tcx, &Default::default()); self.check(item.hir_id, impl_vis).generics().predicates(); - for impl_item_ref in impl_item_refs { + for impl_item_ref in items { let impl_item = tcx.hir().impl_item(impl_item_ref.id); - let impl_item_vis = if trait_ref.is_none() { + let impl_item_vis = if of_trait.is_none() { min( ty::Visibility::from_hir(&impl_item.vis, item.hir_id, tcx), impl_vis, diff --git a/src/librustc_resolve/lifetimes.rs b/src/librustc_resolve/lifetimes.rs index d6143eec73c00..5fae8f3318743 100644 --- a/src/librustc_resolve/lifetimes.rs +++ b/src/librustc_resolve/lifetimes.rs @@ -416,11 +416,11 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { | hir::ItemKind::Union(_, ref generics) | hir::ItemKind::Trait(_, _, ref generics, ..) | hir::ItemKind::TraitAlias(ref generics, ..) - | hir::ItemKind::Impl(_, _, _, ref generics, ..) => { + | hir::ItemKind::Impl { ref generics, .. } => { // Impls permit `'_` to be used and it is equivalent to "some fresh lifetime name". // This is not true for other kinds of items.x let track_lifetime_uses = match item.kind { - hir::ItemKind::Impl(..) => true, + hir::ItemKind::Impl { .. } => true, _ => false, }; // These kinds of items have only early-bound lifetime parameters. @@ -1638,7 +1638,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } match parent.kind { hir::ItemKind::Trait(_, _, ref generics, ..) - | hir::ItemKind::Impl(_, _, _, ref generics, ..) => { + | hir::ItemKind::Impl { ref generics, .. } => { index += generics.params.len() as u32; } _ => {} @@ -2067,12 +2067,12 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } Node::ImplItem(&hir::ImplItem { kind: hir::ImplItemKind::Method(_, body), .. }) => { - if let hir::ItemKind::Impl(.., ref self_ty, ref impl_items) = + if let hir::ItemKind::Impl { ref self_ty, ref items, .. } = self.tcx.hir().expect_item(self.tcx.hir().get_parent_item(parent)).kind { impl_self = Some(self_ty); assoc_item_kind = - impl_items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind); + items.iter().find(|ii| ii.id.hir_id == parent).map(|ii| ii.kind); } Some(body) } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 5412533fce7d8..537fe198a0c39 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -405,9 +405,9 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> { { Some(impl_id) => match self.tcx.hir().get_if_local(impl_id) { Some(Node::Item(item)) => match item.kind { - hir::ItemKind::Impl(.., ref ty, _) => { + hir::ItemKind::Impl { ref self_ty, .. } => { let mut qualname = String::from("<"); - qualname.push_str(&self.tcx.hir().hir_to_pretty_string(ty.hir_id)); + qualname.push_str(&self.tcx.hir().hir_to_pretty_string(self_ty.hir_id)); let trait_id = self.tcx.trait_id_of_impl(impl_id); let mut decl_id = None; diff --git a/src/librustc_traits/lowering/environment.rs b/src/librustc_traits/lowering/environment.rs index 315efe5cf71e7..7df27e67d5b1c 100644 --- a/src/librustc_traits/lowering/environment.rs +++ b/src/librustc_traits/lowering/environment.rs @@ -195,8 +195,8 @@ crate fn environment(tcx: TyCtxt<'_>, def_id: DefId) -> Environment<'_> { }, Node::Item(item) => match item.kind { - ItemKind::Impl(.., Some(..), _, _) => NodeKind::TraitImpl, - ItemKind::Impl(.., None, _, _) => NodeKind::InherentImpl, + ItemKind::Impl { of_trait: Some(_), .. } => NodeKind::TraitImpl, + ItemKind::Impl { of_trait: None, .. } => NodeKind::InherentImpl, ItemKind::Fn(..) => NodeKind::Fn, _ => NodeKind::Other, }, diff --git a/src/librustc_ty/ty.rs b/src/librustc_ty/ty.rs index fc8beb67e4ada..d47e54366b550 100644 --- a/src/librustc_ty/ty.rs +++ b/src/librustc_ty/ty.rs @@ -128,8 +128,8 @@ fn associated_item(tcx: TyCtxt<'_>, def_id: DefId) -> ty::AssocItem { let parent_def_id = tcx.hir().local_def_id(parent_id); let parent_item = tcx.hir().expect_item(parent_id); match parent_item.kind { - hir::ItemKind::Impl(.., ref impl_item_refs) => { - if let Some(impl_item_ref) = impl_item_refs.iter().find(|i| i.id.hir_id == id) { + hir::ItemKind::Impl { ref items, .. } => { + if let Some(impl_item_ref) = items.iter().find(|i| i.id.hir_id == id) { let assoc_item = associated_item_from_impl_item_ref(tcx, parent_def_id, impl_item_ref); debug_assert_eq!(assoc_item.def_id, def_id); @@ -194,8 +194,8 @@ fn associated_item_def_ids(tcx: TyCtxt<'_>, def_id: DefId) -> &[DefId] { .map(|trait_item_ref| trait_item_ref.id) .map(|id| tcx.hir().local_def_id(id.hir_id)), ), - hir::ItemKind::Impl(.., ref impl_item_refs) => tcx.arena.alloc_from_iter( - impl_item_refs + hir::ItemKind::Impl { ref items, .. } => tcx.arena.alloc_from_iter( + items .iter() .map(|impl_item_ref| impl_item_ref.id) .map(|id| tcx.hir().local_def_id(id.hir_id)), diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index dff68b9986cc9..4affdc4a9d64e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1709,17 +1709,11 @@ pub fn check_item_type<'tcx>(tcx: TyCtxt<'tcx>, it: &'tcx hir::Item<'tcx>) { check_enum(tcx, it.span, &enum_definition.variants, it.hir_id); } hir::ItemKind::Fn(..) => {} // entirely within check_item_body - hir::ItemKind::Impl(.., ref impl_item_refs) => { + hir::ItemKind::Impl { ref items, .. } => { debug!("ItemKind::Impl {} with id {}", it.ident, it.hir_id); let impl_def_id = tcx.hir().local_def_id(it.hir_id); if let Some(impl_trait_ref) = tcx.impl_trait_ref(impl_def_id) { - check_impl_items_against_trait( - tcx, - it.span, - impl_def_id, - impl_trait_ref, - impl_item_refs, - ); + check_impl_items_against_trait(tcx, it.span, impl_def_id, impl_trait_ref, items); let trait_def_id = impl_trait_ref.def_id; check_on_unimplemented(tcx, trait_def_id, it); } diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index a496a6e12ce1a..5e91e98a7dfa5 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -97,7 +97,7 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { // // won't be allowed unless there's an *explicit* implementation of `Send` // for `T` - hir::ItemKind::Impl(_, _, defaultness, _, ref trait_ref, ref self_ty, _) => { + hir::ItemKind::Impl { defaultness, ref of_trait, ref self_ty, .. } => { let is_auto = tcx .impl_trait_ref(tcx.hir().local_def_id(item.hir_id)) .map_or(false, |trait_ref| tcx.trait_is_auto(trait_ref.def_id)); @@ -107,11 +107,11 @@ pub fn check_item_well_formed(tcx: TyCtxt<'_>, def_id: DefId) { } match polarity { ty::ImplPolarity::Positive => { - check_impl(tcx, item, self_ty, trait_ref); + check_impl(tcx, item, self_ty, of_trait); } ty::ImplPolarity::Negative => { // FIXME(#27579): what amount of WF checking do we need for neg impls? - if trait_ref.is_some() && !is_auto { + if of_trait.is_some() && !is_auto { struct_span_err!( tcx.sess, item.span, diff --git a/src/librustc_typeck/coherence/builtin.rs b/src/librustc_typeck/coherence/builtin.rs index 8b3db15c02b4e..516dc16d46bd8 100644 --- a/src/librustc_typeck/coherence/builtin.rs +++ b/src/librustc_typeck/coherence/builtin.rs @@ -57,7 +57,7 @@ fn visit_implementation_of_drop(tcx: TyCtxt<'_>, impl_did: DefId) { let impl_hir_id = tcx.hir().as_local_hir_id(impl_did).expect("foreign Drop impl on non-ADT"); let sp = match tcx.hir().expect_item(impl_hir_id).kind { - ItemKind::Impl(.., ty, _) => ty.span, + ItemKind::Impl { self_ty, .. } => self_ty.span, _ => bug!("expected Drop impl item"), }; @@ -94,7 +94,7 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) { Ok(()) => {} Err(CopyImplementationError::InfrigingFields(fields)) => { let item = tcx.hir().expect_item(impl_hir_id); - let span = if let ItemKind::Impl(.., Some(ref tr), _, _) = item.kind { + let span = if let ItemKind::Impl { of_trait: Some(ref tr), .. } = item.kind { tr.path.span } else { span @@ -113,7 +113,8 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: DefId) { } Err(CopyImplementationError::NotAnAdt) => { let item = tcx.hir().expect_item(impl_hir_id); - let span = if let ItemKind::Impl(.., ref ty, _) = item.kind { ty.span } else { span }; + let span = + if let ItemKind::Impl { self_ty, .. } = item.kind { self_ty.span } else { span }; struct_span_err!( tcx.sess, @@ -490,7 +491,7 @@ pub fn coerce_unsized_info<'tcx>(tcx: TyCtxt<'tcx>, impl_did: DefId) -> CoerceUn return err_info; } else if diff_fields.len() > 1 { let item = tcx.hir().expect_item(impl_hir_id); - let span = if let ItemKind::Impl(.., Some(ref t), _, _) = item.kind { + let span = if let ItemKind::Impl { of_trait: Some(ref t), .. } = item.kind { t.path.span } else { tcx.hir().span(impl_hir_id) diff --git a/src/librustc_typeck/coherence/inherent_impls.rs b/src/librustc_typeck/coherence/inherent_impls.rs index 673c1bd9fd831..d313e32fc20e0 100644 --- a/src/librustc_typeck/coherence/inherent_impls.rs +++ b/src/librustc_typeck/coherence/inherent_impls.rs @@ -47,7 +47,7 @@ struct InherentCollect<'tcx> { impl ItemLikeVisitor<'v> for InherentCollect<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { let ty = match item.kind { - hir::ItemKind::Impl(.., None, ref ty, _) => ty, + hir::ItemKind::Impl { of_trait: None, ref self_ty, .. } => self_ty, _ => return, }; diff --git a/src/librustc_typeck/coherence/orphan.rs b/src/librustc_typeck/coherence/orphan.rs index 1878f9385a891..9ba8fa4247f26 100644 --- a/src/librustc_typeck/coherence/orphan.rs +++ b/src/librustc_typeck/coherence/orphan.rs @@ -27,7 +27,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { fn visit_item(&mut self, item: &hir::Item<'_>) { let def_id = self.tcx.hir().local_def_id(item.hir_id); // "Trait" impl - if let hir::ItemKind::Impl(.., generics, Some(tr), impl_ty, _) = &item.kind { + if let hir::ItemKind::Impl { generics, of_trait: Some(ref tr), self_ty, .. } = &item.kind { debug!( "coherence2::orphan check: trait impl {}", self.tcx.hir().node_to_string(item.hir_id) @@ -72,7 +72,7 @@ impl ItemLikeVisitor<'v> for OrphanChecker<'tcx> { let msg = format!("{} is not defined in the current crate{}", ty, postfix); if *is_target_ty { // Point at `D` in `impl for C in D` - err.span_label(impl_ty.span, &msg); + err.span_label(self_ty.span, &msg); } else { // Point at `C` in `impl for C in D` err.span_label(tr.path.span, &msg); diff --git a/src/librustc_typeck/coherence/unsafety.rs b/src/librustc_typeck/coherence/unsafety.rs index 3f4035b0998d6..48b96886d3a71 100644 --- a/src/librustc_typeck/coherence/unsafety.rs +++ b/src/librustc_typeck/coherence/unsafety.rs @@ -88,7 +88,7 @@ impl UnsafetyChecker<'tcx> { impl ItemLikeVisitor<'v> for UnsafetyChecker<'tcx> { fn visit_item(&mut self, item: &'v hir::Item<'v>) { - if let hir::ItemKind::Impl(unsafety, polarity, _, ref generics, ..) = item.kind { + if let hir::ItemKind::Impl { unsafety, polarity, ref generics, .. } = item.kind { self.check_unsafety_coherence(item, Some(generics), unsafety, polarity); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index dca3289747e4c..a03b9f747372e 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -184,7 +184,7 @@ fn reject_placeholder_type_signatures_in_item(tcx: TyCtxt<'tcx>, item: &'tcx hir | hir::ItemKind::Enum(_, generics) | hir::ItemKind::TraitAlias(generics, _) | hir::ItemKind::Trait(_, _, generics, ..) - | hir::ItemKind::Impl(_, _, _, generics, ..) + | hir::ItemKind::Impl { generics, .. } | hir::ItemKind::Struct(_, generics) => (generics, true), hir::ItemKind::OpaqueTy(hir::OpaqueTy { generics, .. }) | hir::ItemKind::TyAlias(_, generics) => (generics, false), @@ -401,7 +401,7 @@ fn type_param_predicates( Node::Item(item) => { match item.kind { ItemKind::Fn(.., ref generics, _) - | ItemKind::Impl(_, _, _, ref generics, ..) + | ItemKind::Impl { ref generics, .. } | ItemKind::TyAlias(_, ref generics) | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) | ItemKind::Enum(_, ref generics) @@ -531,7 +531,7 @@ fn convert_item(tcx: TyCtxt<'_>, item_id: hir::HirId) { tcx.predicates_of(def_id); convert_enum_variant_types(tcx, def_id, &enum_definition.variants); } - hir::ItemKind::Impl(..) => { + hir::ItemKind::Impl { .. } => { tcx.generics_of(def_id); tcx.type_of(def_id); tcx.impl_trait_ref(def_id); @@ -1052,9 +1052,7 @@ fn generics_of(tcx: TyCtxt<'_>, def_id: DefId) -> &ty::Generics { Node::Item(item) => { match item.kind { - ItemKind::Fn(.., ref generics, _) | ItemKind::Impl(_, _, _, ref generics, ..) => { - generics - } + ItemKind::Fn(.., ref generics, _) | ItemKind::Impl { ref generics, .. } => generics, ItemKind::TyAlias(_, ref generics) | ItemKind::Enum(_, ref generics) @@ -1338,7 +1336,9 @@ fn type_of(tcx: TyCtxt<'_>, def_id: DefId) -> Ty<'_> { icx.to_ty(ty) } } - ItemKind::TyAlias(ref ty, _) | ItemKind::Impl(.., ref ty, _) => icx.to_ty(ty), + ItemKind::TyAlias(ref self_ty, _) | ItemKind::Impl { ref self_ty, .. } => { + icx.to_ty(self_ty) + } ItemKind::Fn(..) => { let substs = InternalSubsts::identity_for_item(tcx, def_id); tcx.mk_fn_def(def_id, substs) @@ -1956,12 +1956,10 @@ fn impl_trait_ref(tcx: TyCtxt<'_>, def_id: DefId) -> Option> { let hir_id = tcx.hir().as_local_hir_id(def_id).unwrap(); match tcx.hir().expect_item(hir_id).kind { - hir::ItemKind::Impl(.., ref opt_trait_ref, _, _) => { - opt_trait_ref.as_ref().map(|ast_trait_ref| { - let selfty = tcx.type_of(def_id); - AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) - }) - } + hir::ItemKind::Impl { ref of_trait, .. } => of_trait.as_ref().map(|ast_trait_ref| { + let selfty = tcx.type_of(def_id); + AstConv::instantiate_mono_trait_ref(&icx, ast_trait_ref, selfty) + }), _ => bug!(), } } @@ -1971,19 +1969,21 @@ fn impl_polarity(tcx: TyCtxt<'_>, def_id: DefId) -> ty::ImplPolarity { let is_rustc_reservation = tcx.has_attr(def_id, sym::rustc_reservation_impl); let item = tcx.hir().expect_item(hir_id); match &item.kind { - hir::ItemKind::Impl(_, hir::ImplPolarity::Negative, ..) => { + hir::ItemKind::Impl { polarity: hir::ImplPolarity::Negative, .. } => { if is_rustc_reservation { tcx.sess.span_err(item.span, "reservation impls can't be negative"); } ty::ImplPolarity::Negative } - hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, None, _, _) => { + hir::ItemKind::Impl { polarity: hir::ImplPolarity::Positive, of_trait: None, .. } => { if is_rustc_reservation { tcx.sess.span_err(item.span, "reservation impls can't be inherent"); } ty::ImplPolarity::Positive } - hir::ItemKind::Impl(_, hir::ImplPolarity::Positive, _, _, Some(_tr), _, _) => { + hir::ItemKind::Impl { + polarity: hir::ImplPolarity::Positive, of_trait: Some(_), .. + } => { if is_rustc_reservation { ty::ImplPolarity::Reservation } else { @@ -2142,7 +2142,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat Node::Item(item) => { match item.kind { - ItemKind::Impl(_, _, defaultness, ref generics, ..) => { + ItemKind::Impl { defaultness, ref generics, .. } => { if defaultness.is_default() { is_default_impl_trait = tcx.impl_trait_ref(def_id); } @@ -2359,7 +2359,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat // before uses of `U`. This avoids false ambiguity errors // in trait checking. See `setup_constraining_predicates` // for details. - if let Node::Item(&Item { kind: ItemKind::Impl(..), .. }) = node { + if let Node::Item(&Item { kind: ItemKind::Impl { .. }, .. }) = node { let self_ty = tcx.type_of(def_id); let trait_ref = tcx.impl_trait_ref(def_id); cgp::setup_constraining_predicates( diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index fb87b285fa29f..9ee4e7c48190d 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -75,10 +75,10 @@ struct ImplWfCheck<'tcx> { impl ItemLikeVisitor<'tcx> for ImplWfCheck<'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) { - if let hir::ItemKind::Impl(.., ref impl_item_refs) = item.kind { + if let hir::ItemKind::Impl { ref items, .. } = item.kind { let impl_def_id = self.tcx.hir().local_def_id(item.hir_id); - enforce_impl_params_are_constrained(self.tcx, impl_def_id, impl_item_refs); - enforce_impl_items_are_distinct(self.tcx, impl_item_refs); + enforce_impl_params_are_constrained(self.tcx, impl_def_id, items); + enforce_impl_items_are_distinct(self.tcx, items); } } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index c7e0f1e9e704b..342eaad3a8f91 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -331,7 +331,7 @@ pub fn build_impl( let for_ = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { match tcx.hir().expect_item(hir_id).kind { - hir::ItemKind::Impl(.., ref t, _) => t.clean(cx), + hir::ItemKind::Impl { self_ty, .. } => self_ty.clean(cx), _ => panic!("did given to build_impl was not an impl"), } } else { @@ -351,9 +351,9 @@ pub fn build_impl( let predicates = tcx.explicit_predicates_of(did); let (trait_items, generics) = if let Some(hir_id) = tcx.hir().as_local_hir_id(did) { match tcx.hir().expect_item(hir_id).kind { - hir::ItemKind::Impl(.., ref gen, _, _, ref item_ids) => ( - item_ids.iter().map(|ii| tcx.hir().impl_item(ii.id).clean(cx)).collect::>(), - gen.clean(cx), + hir::ItemKind::Impl { ref generics, ref items, .. } => ( + items.iter().map(|item| tcx.hir().impl_item(item.id).clean(cx)).collect::>(), + generics.clean(cx), ), _ => panic!("did given to build_impl was not an impl"), } diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index f899e722a5615..05d4141568981 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -905,8 +905,8 @@ impl<'a, 'hir> intravisit::Visitor<'hir> for HirCollector<'a, 'hir> { } fn visit_item(&mut self, item: &'hir hir::Item) { - let name = if let hir::ItemKind::Impl(.., ref ty, _) = item.kind { - self.map.hir_to_pretty_string(ty.hir_id) + let name = if let hir::ItemKind::Impl { ref self_ty, .. } = item.kind { + self.map.hir_to_pretty_string(self_ty.hir_id) } else { item.ident.to_string() }; diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 5fa9270959cca..fdff18779e795 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -558,27 +558,27 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> { om.trait_aliases.push(t); } - hir::ItemKind::Impl( + hir::ItemKind::Impl { unsafety, polarity, defaultness, ref generics, - ref trait_, - for_, - ref item_ids, - ) => { + ref of_trait, + self_ty, + ref items, + } => { // Don't duplicate impls when inlining or if it's implementing a trait, we'll pick // them up regardless of where they're located. - if !self.inlining && trait_.is_none() { + if !self.inlining && of_trait.is_none() { let items = - item_ids.iter().map(|ii| self.cx.tcx.hir().impl_item(ii.id)).collect(); + items.iter().map(|item| self.cx.tcx.hir().impl_item(item.id)).collect(); let i = Impl { unsafety, polarity, defaultness, generics, - trait_, - for_, + trait_: of_trait, + for_: self_ty, items, attrs: &item.attrs, id: item.hir_id,