From 87e73c1f8288823e689ca254cdee9ab6c1723154 Mon Sep 17 00:00:00 2001 From: varkor Date: Wed, 31 Jul 2019 01:51:20 +0100 Subject: [PATCH 01/22] Remove redundant method with const variable resolution --- src/librustc/infer/canonical/canonicalizer.rs | 2 +- src/librustc/infer/mod.rs | 27 +++---------------- src/librustc/ty/relate.rs | 12 ++++----- 3 files changed, 10 insertions(+), 31 deletions(-) diff --git a/src/librustc/infer/canonical/canonicalizer.rs b/src/librustc/infer/canonical/canonicalizer.rs index 3d57a89493e1e..db724875b8aa3 100644 --- a/src/librustc/infer/canonical/canonicalizer.rs +++ b/src/librustc/infer/canonical/canonicalizer.rs @@ -693,7 +693,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> { const_var: &'tcx ty::Const<'tcx> ) -> &'tcx ty::Const<'tcx> { let infcx = self.infcx.expect("encountered const-var without infcx"); - let bound_to = infcx.resolve_const_var(const_var); + let bound_to = infcx.shallow_resolve(const_var); if bound_to != const_var { self.fold_const(bound_to) } else { diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 663acd67dcd83..e1d77a97c1160 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -1351,23 +1351,6 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { } } - pub fn resolve_const_var( - &self, - ct: &'tcx ty::Const<'tcx> - ) -> &'tcx ty::Const<'tcx> { - if let ty::Const { val: ConstValue::Infer(InferConst::Var(v)), .. } = ct { - self.const_unification_table - .borrow_mut() - .probe_value(*v) - .val - .known() - .map(|c| self.resolve_const_var(c)) - .unwrap_or(ct) - } else { - ct - } - } - pub fn fully_resolve>(&self, value: &T) -> FixupResult<'tcx, T> { /*! * Attempts to resolve all type/region/const variables in @@ -1586,7 +1569,7 @@ impl<'a, 'tcx> ShallowResolver<'a, 'tcx> { // it can be resolved to an int/float variable, which // can then be recursively resolved, hence the // recursion. Note though that we prevent type - // variables from unifyxing to other type variables + // variables from unifying to other type variables // directly (though they may be embedded // structurally), and we prevent cycles in any case, // so this recursion should always be of very limited @@ -1626,17 +1609,15 @@ impl<'a, 'tcx> TypeFolder<'tcx> for ShallowResolver<'a, 'tcx> { } fn fold_const(&mut self, ct: &'tcx ty::Const<'tcx>) -> &'tcx ty::Const<'tcx> { - match ct { - ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } => { + if let ty::Const { val: ConstValue::Infer(InferConst::Var(vid)), .. } = ct { self.infcx.const_unification_table .borrow_mut() .probe_value(*vid) .val .known() - .map(|c| self.fold_const(c)) .unwrap_or(ct) - } - _ => ct, + } else { + ct } } } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index a6bfc2dee613b..ca54f63b83afe 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -594,13 +594,11 @@ pub fn super_relate_consts>( ty: a.ty, })) } - (ConstValue::ByRef { .. }, _) => { - bug!( - "non-Scalar ConstValue encountered in super_relate_consts {:?} {:?}", - a, - b, - ); - } + + // FIXME(const_generics): we should either handle `Scalar::Ptr` or add a comment + // saying that we're not handling it intentionally. + + // FIXME(const_generics): handle `ConstValue::ByRef` and `ConstValue::Slice`. // FIXME(const_generics): this is wrong, as it is a projection (ConstValue::Unevaluated(a_def_id, a_substs), From 804f0f3c20455bd8a34a903bcf9449297c3de88c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 30 Jul 2019 13:32:57 -0400 Subject: [PATCH 02/22] Unify spanned and non-spanned Attribute ctors There is no difference in the code/arguments, so go with the shorter name throughout the code. --- src/librustc/hir/lowering.rs | 2 +- src/libsyntax/attr/mod.rs | 18 ++++-------------- src/libsyntax/ext/build.rs | 2 +- src/libsyntax/ext/expand.rs | 4 ++-- 4 files changed, 8 insertions(+), 18 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 026c3cc6f95b2..c403fb99a9767 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -5168,7 +5168,7 @@ impl<'a> LoweringContext<'a> { let uc_nested = attr::mk_nested_word_item(uc_ident); attr::mk_list_item(e.span, allow_ident, vec![uc_nested]) }; - attr::mk_spanned_attr_outer(e.span, attr::mk_attr_id(), allow) + attr::mk_attr_outer(e.span, attr::mk_attr_id(), allow) }; let attrs = vec![attr]; diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 7be21ff9029a5..ec26ea8d543d3 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -376,37 +376,27 @@ pub fn mk_attr_id() -> AttrId { AttrId(id) } -/// Returns an inner attribute with the given value. -pub fn mk_attr_inner(span: Span, id: AttrId, item: MetaItem) -> Attribute { - mk_spanned_attr_inner(span, id, item) -} - /// Returns an inner attribute with the given value and span. -pub fn mk_spanned_attr_inner(sp: Span, id: AttrId, item: MetaItem) -> Attribute { +pub fn mk_attr_inner(span: Span, id: AttrId, item: MetaItem) -> Attribute { Attribute { id, style: ast::AttrStyle::Inner, path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, - span: sp, + span, } } -/// Returns an outer attribute with the given value. -pub fn mk_attr_outer(span: Span, id: AttrId, item: MetaItem) -> Attribute { - mk_spanned_attr_outer(span, id, item) -} - /// Returns an outer attribute with the given value and span. -pub fn mk_spanned_attr_outer(sp: Span, id: AttrId, item: MetaItem) -> Attribute { +pub fn mk_attr_outer(span: Span, id: AttrId, item: MetaItem) -> Attribute { Attribute { id, style: ast::AttrStyle::Outer, path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, - span: sp, + span, } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index b30fefe5b9676..2b0feb7f4b367 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -1135,7 +1135,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute { - attr::mk_spanned_attr_outer(sp, attr::mk_attr_id(), mi) + attr::mk_attr_outer(sp, attr::mk_attr_id(), mi) } fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index cd602d08c5baa..10d5da81ceef3 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1341,8 +1341,8 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { let meta = attr::mk_list_item(DUMMY_SP, Ident::with_empty_ctxt(sym::doc), items); match at.style { - ast::AttrStyle::Inner => *at = attr::mk_spanned_attr_inner(at.span, at.id, meta), - ast::AttrStyle::Outer => *at = attr::mk_spanned_attr_outer(at.span, at.id, meta), + ast::AttrStyle::Inner => *at = attr::mk_attr_inner(at.span, at.id, meta), + ast::AttrStyle::Outer => *at = attr::mk_attr_outer(at.span, at.id, meta), } } else { noop_visit_attribute(at, self) From 0a42badd4c9bfb6cb693f9a2105cc5b2cc674f63 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 30 Jul 2019 13:50:22 -0400 Subject: [PATCH 03/22] Remove AttrId from Attribute constructors --- src/librustc/hir/lowering.rs | 2 +- src/libsyntax/attr/mod.rs | 30 ++++++++++--------- src/libsyntax/ext/build.rs | 2 +- src/libsyntax/ext/expand.rs | 12 +++++--- src/libsyntax/parse/attr.rs | 4 +-- src/libsyntax/print/pprust.rs | 4 +-- src/libsyntax_ext/standard_library_imports.rs | 1 - src/libsyntax_ext/test_harness.rs | 1 - 8 files changed, 30 insertions(+), 26 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index c403fb99a9767..145d044b52130 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -5168,7 +5168,7 @@ impl<'a> LoweringContext<'a> { let uc_nested = attr::mk_nested_word_item(uc_ident); attr::mk_list_item(e.span, allow_ident, vec![uc_nested]) }; - attr::mk_attr_outer(e.span, attr::mk_attr_id(), allow) + attr::mk_attr_outer(e.span, allow) }; let attrs = vec![attr]; diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index ec26ea8d543d3..11c1b1c56c71b 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -6,9 +6,10 @@ pub use builtin::*; pub use IntType::*; pub use ReprAttr::*; pub use StabilityLevel::*; +pub use crate::ast::Attribute; use crate::ast; -use crate::ast::{AttrId, Attribute, AttrStyle, Name, Ident, Path, PathSegment}; +use crate::ast::{AttrId, AttrStyle, Name, Ident, Path, PathSegment}; use crate::ast::{MetaItem, MetaItemKind, NestedMetaItem}; use crate::ast::{Lit, LitKind, Expr, Item, Local, Stmt, StmtKind, GenericParam}; use crate::mut_visit::visit_clobber; @@ -328,13 +329,14 @@ impl Attribute { let meta = mk_name_value_item_str( Ident::with_empty_ctxt(sym::doc), dummy_spanned(Symbol::intern(&strip_doc_comment_decoration(&comment.as_str())))); - let mut attr = if self.style == ast::AttrStyle::Outer { - mk_attr_outer(self.span, self.id, meta) - } else { - mk_attr_inner(self.span, self.id, meta) - }; - attr.is_sugared_doc = true; - f(&attr) + f(&Attribute { + id: self.id, + style: self.style, + path: meta.path, + tokens: meta.node.tokens(meta.span), + is_sugared_doc: true, + span: self.span, + }) } else { f(self) } @@ -377,9 +379,9 @@ pub fn mk_attr_id() -> AttrId { } /// Returns an inner attribute with the given value and span. -pub fn mk_attr_inner(span: Span, id: AttrId, item: MetaItem) -> Attribute { +pub fn mk_attr_inner(span: Span, item: MetaItem) -> Attribute { Attribute { - id, + id: mk_attr_id(), style: ast::AttrStyle::Inner, path: item.path, tokens: item.node.tokens(item.span), @@ -389,9 +391,9 @@ pub fn mk_attr_inner(span: Span, id: AttrId, item: MetaItem) -> Attribute { } /// Returns an outer attribute with the given value and span. -pub fn mk_attr_outer(span: Span, id: AttrId, item: MetaItem) -> Attribute { +pub fn mk_attr_outer(span: Span, item: MetaItem) -> Attribute { Attribute { - id, + id: mk_attr_id(), style: ast::AttrStyle::Outer, path: item.path, tokens: item.node.tokens(item.span), @@ -400,12 +402,12 @@ pub fn mk_attr_outer(span: Span, id: AttrId, item: MetaItem) -> Attribute { } } -pub fn mk_sugared_doc_attr(id: AttrId, text: Symbol, span: Span) -> Attribute { +pub fn mk_sugared_doc_attr(text: Symbol, span: Span) -> Attribute { let style = doc_comment_style(&text.as_str()); let lit_kind = LitKind::Str(text, ast::StrStyle::Cooked); let lit = Lit::from_lit_kind(lit_kind, span); Attribute { - id, + id: mk_attr_id(), style, path: Path::from_ident(Ident::with_empty_ctxt(sym::doc).with_span_pos(span)), tokens: MetaItemKind::NameValue(lit).tokens(span), diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 2b0feb7f4b367..8a7a9e712a303 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -1135,7 +1135,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute { - attr::mk_attr_outer(sp, attr::mk_attr_id(), mi) + attr::mk_attr_outer(sp, mi) } fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem { diff --git a/src/libsyntax/ext/expand.rs b/src/libsyntax/ext/expand.rs index 10d5da81ceef3..1e9e16d72f829 100644 --- a/src/libsyntax/ext/expand.rs +++ b/src/libsyntax/ext/expand.rs @@ -1340,10 +1340,14 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } let meta = attr::mk_list_item(DUMMY_SP, Ident::with_empty_ctxt(sym::doc), items); - match at.style { - ast::AttrStyle::Inner => *at = attr::mk_attr_inner(at.span, at.id, meta), - ast::AttrStyle::Outer => *at = attr::mk_attr_outer(at.span, at.id, meta), - } + *at = attr::Attribute { + span: at.span, + id: at.id, + style: at.style, + path: meta.path, + tokens: meta.node.tokens(meta.span), + is_sugared_doc: false, + }; } else { noop_visit_attribute(at, self) } diff --git a/src/libsyntax/parse/attr.rs b/src/libsyntax/parse/attr.rs index af484c886ab35..a42da1123600a 100644 --- a/src/libsyntax/parse/attr.rs +++ b/src/libsyntax/parse/attr.rs @@ -53,7 +53,7 @@ impl<'a> Parser<'a> { just_parsed_doc_comment = false; } token::DocComment(s) => { - let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.token.span); + let attr = attr::mk_sugared_doc_attr(s, self.token.span); if attr.style != ast::AttrStyle::Outer { let mut err = self.fatal("expected outer doc comment"); err.note("inner doc comments like this (starting with \ @@ -239,7 +239,7 @@ impl<'a> Parser<'a> { } token::DocComment(s) => { // we need to get the position of this token before we bump. - let attr = attr::mk_sugared_doc_attr(attr::mk_attr_id(), s, self.token.span); + let attr = attr::mk_sugared_doc_attr(s, self.token.span); if attr.style == ast::AttrStyle::Inner { attrs.push(attr); self.bump(); diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 88ff6ee907101..34a47c124528a 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -123,12 +123,12 @@ pub fn print_crate<'a>(cm: &'a SourceMap, let pi_nested = attr::mk_nested_word_item(ast::Ident::with_empty_ctxt(sym::prelude_import)); let list = attr::mk_list_item( DUMMY_SP, ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]); - let fake_attr = attr::mk_attr_inner(DUMMY_SP, attr::mk_attr_id(), list); + let fake_attr = attr::mk_attr_inner(DUMMY_SP, list); s.print_attribute(&fake_attr); // #![no_std] let no_std_meta = attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::no_std)); - let fake_attr = attr::mk_attr_inner(DUMMY_SP, attr::mk_attr_id(), no_std_meta); + let fake_attr = attr::mk_attr_inner(DUMMY_SP, no_std_meta); s.print_attribute(&fake_attr); } diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs index 81bb32d79a2aa..e1dad90977676 100644 --- a/src/libsyntax_ext/standard_library_imports.rs +++ b/src/libsyntax_ext/standard_library_imports.rs @@ -42,7 +42,6 @@ pub fn inject( krate.module.items.insert(0, P(ast::Item { attrs: vec![attr::mk_attr_outer( DUMMY_SP, - attr::mk_attr_id(), attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::macro_use)) )], vis: dummy_spanned(ast::VisibilityKind::Inherited), diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs index 848c797856ea9..c65922339e9f5 100644 --- a/src/libsyntax_ext/test_harness.rs +++ b/src/libsyntax_ext/test_harness.rs @@ -161,7 +161,6 @@ impl MutVisitor for EntryPointCleaner { let allow_dead_code_item = attr::mk_list_item(DUMMY_SP, allow_ident, vec![dc_nested]); let allow_dead_code = attr::mk_attr_outer(DUMMY_SP, - attr::mk_attr_id(), allow_dead_code_item); ast::Item { From b2c5065b0434f0986e45bdf5a5d0028972e8104c Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 30 Jul 2019 14:12:52 -0400 Subject: [PATCH 04/22] Remove Span argument from ExtCtxt::attribute MetaItem.span was always equivalent --- src/libsyntax/attr/builtin.rs | 2 +- src/libsyntax/ext/build.rs | 6 +++--- src/libsyntax/ext/proc_macro.rs | 4 ++-- src/libsyntax_ext/deriving/clone.rs | 2 +- src/libsyntax_ext/deriving/cmp/eq.rs | 2 +- src/libsyntax_ext/deriving/cmp/ord.rs | 2 +- src/libsyntax_ext/deriving/cmp/partial_eq.rs | 2 +- src/libsyntax_ext/deriving/cmp/partial_ord.rs | 4 ++-- src/libsyntax_ext/deriving/default.rs | 2 +- src/libsyntax_ext/deriving/generic/mod.rs | 5 ++--- src/libsyntax_ext/global_allocator.rs | 2 +- src/libsyntax_ext/proc_macro_harness.rs | 4 ++-- src/libsyntax_ext/test.rs | 7 +++---- src/libsyntax_ext/test_harness.rs | 2 +- 14 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index dbf31ad014832..eabb6302d463b 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -929,7 +929,7 @@ pub fn find_transparency( pub fn check_builtin_macro_attribute(ecx: &ExtCtxt<'_>, meta_item: &MetaItem, name: Symbol) { // All the built-in macro attributes are "words" at the moment. let template = AttributeTemplate { word: true, list: None, name_value_str: None }; - let attr = ecx.attribute(meta_item.span, meta_item.clone()); + let attr = ecx.attribute(meta_item.clone()); check_builtin_attribute(ecx.parse_sess, &attr, name, template); } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 8a7a9e712a303..ea2c1fd707811 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -259,7 +259,7 @@ pub trait AstBuilder { generics: Generics) -> P; fn item_ty(&self, span: Span, name: Ident, ty: P) -> P; - fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute; + fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute; fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem; @@ -1134,8 +1134,8 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.item_ty_poly(span, name, ty, Generics::default()) } - fn attribute(&self, sp: Span, mi: ast::MetaItem) -> ast::Attribute { - attr::mk_attr_outer(sp, mi) + fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { + attr::mk_attr_outer(mi.span, mi) } fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem { diff --git a/src/libsyntax/ext/proc_macro.rs b/src/libsyntax/ext/proc_macro.rs index 425b9813f5904..d1fabf963b5d9 100644 --- a/src/libsyntax/ext/proc_macro.rs +++ b/src/libsyntax/ext/proc_macro.rs @@ -239,11 +239,11 @@ crate fn add_derived_markers( item.visit_attrs(|attrs| { if names.contains(&sym::Eq) && names.contains(&sym::PartialEq) { let meta = cx.meta_word(span, sym::structural_match); - attrs.push(cx.attribute(span, meta)); + attrs.push(cx.attribute(meta)); } if names.contains(&sym::Copy) { let meta = cx.meta_word(span, sym::rustc_copy_clone_marker); - attrs.push(cx.attribute(span, meta)); + attrs.push(cx.attribute(meta)); } }); } diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index 9a890a06e0396..350eacc3230ef 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -77,7 +77,7 @@ pub fn expand_deriving_clone(cx: &mut ExtCtxt<'_>, } let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(span, inline)]; + let attrs = vec![cx.attribute(inline)]; let trait_def = TraitDef { span, attributes: Vec::new(), diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index 1d981e0ff7906..5698a8e382391 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -17,7 +17,7 @@ pub fn expand_deriving_eq(cx: &mut ExtCtxt<'_>, let inline = cx.meta_word(span, sym::inline); let hidden = cx.meta_list_item_word(span, sym::hidden); let doc = cx.meta_list(span, sym::doc, vec![hidden]); - let attrs = vec![cx.attribute(span, inline), cx.attribute(span, doc)]; + let attrs = vec![cx.attribute(inline), cx.attribute(doc)]; let trait_def = TraitDef { span, attributes: Vec::new(), diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs index 844865d57c7ad..8405d28984217 100644 --- a/src/libsyntax_ext/deriving/cmp/ord.rs +++ b/src/libsyntax_ext/deriving/cmp/ord.rs @@ -15,7 +15,7 @@ pub fn expand_deriving_ord(cx: &mut ExtCtxt<'_>, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(span, inline)]; + let attrs = vec![cx.attribute(inline)]; let trait_def = TraitDef { span, attributes: Vec::new(), diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index 732bb234389a0..4ab136538877a 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -63,7 +63,7 @@ pub fn expand_deriving_partial_eq(cx: &mut ExtCtxt<'_>, macro_rules! md { ($name:expr, $f:ident) => { { let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(span, inline)]; + let attrs = vec![cx.attribute(inline)]; MethodDef { name: $name, generics: LifetimeBounds::empty(), diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index a30a7d78222f4..18354e94815b5 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -19,7 +19,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt<'_>, macro_rules! md { ($name:expr, $op:expr, $equal:expr) => { { let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(span, inline)]; + let attrs = vec![cx.attribute(inline)]; MethodDef { name: $name, generics: LifetimeBounds::empty(), @@ -43,7 +43,7 @@ pub fn expand_deriving_partial_ord(cx: &mut ExtCtxt<'_>, PathKind::Std)); let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(span, inline)]; + let attrs = vec![cx.attribute(inline)]; let partial_cmp_def = MethodDef { name: "partial_cmp", diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs index fd8e87e2fefd1..e147782db2c06 100644 --- a/src/libsyntax_ext/deriving/default.rs +++ b/src/libsyntax_ext/deriving/default.rs @@ -16,7 +16,7 @@ pub fn expand_deriving_default(cx: &mut ExtCtxt<'_>, item: &Annotatable, push: &mut dyn FnMut(Annotatable)) { let inline = cx.meta_word(span, sym::inline); - let attrs = vec![cx.attribute(span, inline)]; + let attrs = vec![cx.attribute(inline)]; let trait_def = TraitDef { span, attributes: Vec::new(), diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 7f27769f236e2..1a4fce3754984 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -666,14 +666,13 @@ impl<'a> TraitDef<'a> { let path = cx.path_all(self.span, false, vec![type_ident], self_params, vec![]); let self_type = cx.ty_path(path); - let attr = cx.attribute(self.span, - cx.meta_word(self.span, sym::automatically_derived)); + let attr = cx.attribute(cx.meta_word(self.span, sym::automatically_derived)); // Just mark it now since we know that it'll end up used downstream attr::mark_used(&attr); let opt_trait_ref = Some(trait_ref); let unused_qual = { let word = cx.meta_list_item_word(self.span, Symbol::intern("unused_qualifications")); - cx.attribute(self.span, cx.meta_list(self.span, sym::allow, vec![word])) + cx.attribute(cx.meta_list(self.span, sym::allow, vec![word])) }; let mut a = vec![attr, unused_qual]; diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs index 33072487e19f4..7225ceb8fc9b7 100644 --- a/src/libsyntax_ext/global_allocator.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -110,7 +110,7 @@ impl AllocFnFactory<'_, '_> { fn attrs(&self) -> Vec { let special = sym::rustc_std_internal_symbol; let special = self.cx.meta_word(self.span, special); - vec![self.cx.attribute(self.span, special)] + vec![self.cx.attribute(special)] } fn arg_ty( diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs index fc6cd5dc94cd5..7c16d82fe3804 100644 --- a/src/libsyntax_ext/proc_macro_harness.rs +++ b/src/libsyntax_ext/proc_macro_harness.rs @@ -337,7 +337,7 @@ fn mk_decls( let hidden = cx.meta_list_item_word(span, sym::hidden); let doc = cx.meta_list(span, sym::doc, vec![hidden]); - let doc_hidden = cx.attribute(span, doc); + let doc_hidden = cx.attribute(doc); let proc_macro = Ident::with_empty_ctxt(sym::proc_macro); let krate = cx.item(span, @@ -394,7 +394,7 @@ fn mk_decls( cx.expr_vec_slice(span, decls), ).map(|mut i| { let attr = cx.meta_word(span, sym::rustc_proc_macro_decls); - i.attrs.push(cx.attribute(span, attr)); + i.attrs.push(cx.attribute(attr)); i.vis = respan(span, ast::VisibilityKind::Public); i }); diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index a2d93d01cec56..ed4ea6b1bc90c 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -36,8 +36,7 @@ pub fn expand_test_case( item.vis = respan(item.vis.span, ast::VisibilityKind::Public); item.ident = item.ident.gensym(); item.attrs.push( - ecx.attribute(sp, - ecx.meta_word(sp, sym::rustc_test_marker)) + ecx.attribute(ecx.meta_word(sp, sym::rustc_test_marker)) ); item }); @@ -150,11 +149,11 @@ pub fn expand_test_or_bench( let mut test_const = cx.item(sp, ast::Ident::new(item.ident.name, sp).gensym(), vec![ // #[cfg(test)] - cx.attribute(attr_sp, cx.meta_list(attr_sp, sym::cfg, vec![ + cx.attribute(cx.meta_list(attr_sp, sym::cfg, vec![ cx.meta_list_item_word(attr_sp, sym::test) ])), // #[rustc_test_marker] - cx.attribute(attr_sp, cx.meta_word(attr_sp, sym::rustc_test_marker)), + cx.attribute(cx.meta_word(attr_sp, sym::rustc_test_marker)), ], // const $ident: test::TestDescAndFn = ast::ItemKind::Const(cx.ty(sp, ast::TyKind::Path(None, test_path("TestDescAndFn"))), diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs index c65922339e9f5..3fae6fc6195c3 100644 --- a/src/libsyntax_ext/test_harness.rs +++ b/src/libsyntax_ext/test_harness.rs @@ -294,7 +294,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P { // #![main] let main_meta = ecx.meta_word(sp, sym::main); - let main_attr = ecx.attribute(sp, main_meta); + let main_attr = ecx.attribute(main_meta); // extern crate test as test_gensym let test_extern_stmt = ecx.stmt_item(sp, ecx.item(sp, From f78bf50dec172630a03eab1d8abb3bfaa14b9627 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 30 Jul 2019 14:18:19 -0400 Subject: [PATCH 05/22] Remove span argument from mk_attr_{inner,outer} Always the same as the passed MetaItem --- src/librustc/hir/lowering.rs | 2 +- src/libsyntax/attr/mod.rs | 8 ++++---- src/libsyntax/ext/build.rs | 2 +- src/libsyntax/print/pprust.rs | 4 ++-- src/libsyntax_ext/standard_library_imports.rs | 1 - src/libsyntax_ext/test_harness.rs | 3 +-- 6 files changed, 9 insertions(+), 11 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 145d044b52130..ff35c3aa3a5eb 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -5168,7 +5168,7 @@ impl<'a> LoweringContext<'a> { let uc_nested = attr::mk_nested_word_item(uc_ident); attr::mk_list_item(e.span, allow_ident, vec![uc_nested]) }; - attr::mk_attr_outer(e.span, allow) + attr::mk_attr_outer(allow) }; let attrs = vec![attr]; diff --git a/src/libsyntax/attr/mod.rs b/src/libsyntax/attr/mod.rs index 11c1b1c56c71b..3e56136b17108 100644 --- a/src/libsyntax/attr/mod.rs +++ b/src/libsyntax/attr/mod.rs @@ -379,26 +379,26 @@ pub fn mk_attr_id() -> AttrId { } /// Returns an inner attribute with the given value and span. -pub fn mk_attr_inner(span: Span, item: MetaItem) -> Attribute { +pub fn mk_attr_inner(item: MetaItem) -> Attribute { Attribute { id: mk_attr_id(), style: ast::AttrStyle::Inner, path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, - span, + span: item.span, } } /// Returns an outer attribute with the given value and span. -pub fn mk_attr_outer(span: Span, item: MetaItem) -> Attribute { +pub fn mk_attr_outer(item: MetaItem) -> Attribute { Attribute { id: mk_attr_id(), style: ast::AttrStyle::Outer, path: item.path, tokens: item.node.tokens(item.span), is_sugared_doc: false, - span, + span: item.span, } } diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index ea2c1fd707811..0791dc94e34b2 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -1135,7 +1135,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { - attr::mk_attr_outer(mi.span, mi) + attr::mk_attr_outer(mi) } fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem { diff --git a/src/libsyntax/print/pprust.rs b/src/libsyntax/print/pprust.rs index 34a47c124528a..372f6fef5e3bd 100644 --- a/src/libsyntax/print/pprust.rs +++ b/src/libsyntax/print/pprust.rs @@ -123,12 +123,12 @@ pub fn print_crate<'a>(cm: &'a SourceMap, let pi_nested = attr::mk_nested_word_item(ast::Ident::with_empty_ctxt(sym::prelude_import)); let list = attr::mk_list_item( DUMMY_SP, ast::Ident::with_empty_ctxt(sym::feature), vec![pi_nested]); - let fake_attr = attr::mk_attr_inner(DUMMY_SP, list); + let fake_attr = attr::mk_attr_inner(list); s.print_attribute(&fake_attr); // #![no_std] let no_std_meta = attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::no_std)); - let fake_attr = attr::mk_attr_inner(DUMMY_SP, no_std_meta); + let fake_attr = attr::mk_attr_inner(no_std_meta); s.print_attribute(&fake_attr); } diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs index e1dad90977676..e8b20e22526d7 100644 --- a/src/libsyntax_ext/standard_library_imports.rs +++ b/src/libsyntax_ext/standard_library_imports.rs @@ -41,7 +41,6 @@ pub fn inject( }; krate.module.items.insert(0, P(ast::Item { attrs: vec![attr::mk_attr_outer( - DUMMY_SP, attr::mk_word_item(ast::Ident::with_empty_ctxt(sym::macro_use)) )], vis: dummy_spanned(ast::VisibilityKind::Inherited), diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs index 3fae6fc6195c3..8cf043f7e767e 100644 --- a/src/libsyntax_ext/test_harness.rs +++ b/src/libsyntax_ext/test_harness.rs @@ -160,8 +160,7 @@ impl MutVisitor for EntryPointCleaner { let dc_nested = attr::mk_nested_word_item(Ident::from_str("dead_code")); let allow_dead_code_item = attr::mk_list_item(DUMMY_SP, allow_ident, vec![dc_nested]); - let allow_dead_code = attr::mk_attr_outer(DUMMY_SP, - allow_dead_code_item); + let allow_dead_code = attr::mk_attr_outer(allow_dead_code_item); ast::Item { id, From c9bd4a05bf9acfaf5e26f7b8b07dae0012c93d92 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 30 Jul 2019 14:49:46 -0400 Subject: [PATCH 06/22] Replace a few Attribute constructors with mk_attr --- src/libsyntax/parse/parser.rs | 11 ++--------- src/libsyntax_ext/plugin_macro_defs.rs | 10 ++-------- src/libsyntax_ext/standard_library_imports.rs | 11 ++--------- 3 files changed, 6 insertions(+), 26 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 7fda9158b4bdf..01d9afab07946 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6396,15 +6396,8 @@ impl<'a> Parser<'a> { self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?; // Record that we fetched the mod from an external file if warn { - let attr = Attribute { - id: attr::mk_attr_id(), - style: ast::AttrStyle::Outer, - path: ast::Path::from_ident( - Ident::with_empty_ctxt(sym::warn_directory_ownership)), - tokens: TokenStream::empty(), - is_sugared_doc: false, - span: DUMMY_SP, - }; + let attr = attr::mk_attr_outer( + attr::mk_word_item(Ident::with_empty_ctxt(sym::warn_directory_ownership))); attr::mark_known(&attr); attrs.push(attr); } diff --git a/src/libsyntax_ext/plugin_macro_defs.rs b/src/libsyntax_ext/plugin_macro_defs.rs index 2fd1a42db95f3..a725f5e46ad1c 100644 --- a/src/libsyntax_ext/plugin_macro_defs.rs +++ b/src/libsyntax_ext/plugin_macro_defs.rs @@ -16,14 +16,8 @@ use syntax_pos::hygiene::{ExpnId, ExpnInfo, ExpnKind, MacroKind}; use std::mem; fn plugin_macro_def(name: Name, span: Span) -> P { - let rustc_builtin_macro = Attribute { - id: attr::mk_attr_id(), - style: AttrStyle::Outer, - path: Path::from_ident(Ident::new(sym::rustc_builtin_macro, span)), - tokens: TokenStream::empty(), - is_sugared_doc: false, - span, - }; + let rustc_builtin_macro = attr::mk_attr_outer( + attr::mk_word_item(Ident::new(sym::rustc_builtin_macro, span))); let parens: TreeAndJoint = TokenTree::Delimited( DelimSpan::from_single(span), token::Paren, TokenStream::empty() diff --git a/src/libsyntax_ext/standard_library_imports.rs b/src/libsyntax_ext/standard_library_imports.rs index e8b20e22526d7..68b13bdd171a9 100644 --- a/src/libsyntax_ext/standard_library_imports.rs +++ b/src/libsyntax_ext/standard_library_imports.rs @@ -4,7 +4,6 @@ use syntax::ext::hygiene::{ExpnId, MacroKind}; use syntax::ptr::P; use syntax::source_map::{ExpnInfo, ExpnKind, dummy_spanned, respan}; use syntax::symbol::{Ident, Symbol, kw, sym}; -use syntax::tokenstream::TokenStream; use syntax_pos::DUMMY_SP; use std::iter; @@ -62,14 +61,8 @@ pub fn inject( )); krate.module.items.insert(0, P(ast::Item { - attrs: vec![ast::Attribute { - style: ast::AttrStyle::Outer, - path: ast::Path::from_ident(ast::Ident::new(sym::prelude_import, span)), - tokens: TokenStream::empty(), - id: attr::mk_attr_id(), - is_sugared_doc: false, - span, - }], + attrs: vec![attr::mk_attr_outer( + attr::mk_word_item(ast::Ident::new(sym::prelude_import, span)))], vis: respan(span.shrink_to_lo(), ast::VisibilityKind::Inherited), node: ast::ItemKind::Use(P(ast::UseTree { prefix: ast::Path { From 0f985817bd9a5dbabb84c5fce523bc55ecbedfed Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 31 Jul 2019 07:40:32 -0400 Subject: [PATCH 07/22] Replace AstBuilder with inherent methods --- .../src/language-features/plugin.md | 8 - src/libsyntax/attr/builtin.rs | 1 - src/libsyntax/diagnostics/plugin.rs | 1 - src/libsyntax/ext/build.rs | 529 +++++------------- src/libsyntax/ext/proc_macro.rs | 1 - src/libsyntax_ext/assert.rs | 1 - src/libsyntax_ext/cfg.rs | 1 - src/libsyntax_ext/concat.rs | 1 - src/libsyntax_ext/deriving/clone.rs | 1 - src/libsyntax_ext/deriving/cmp/eq.rs | 1 - src/libsyntax_ext/deriving/cmp/ord.rs | 1 - src/libsyntax_ext/deriving/cmp/partial_eq.rs | 1 - src/libsyntax_ext/deriving/cmp/partial_ord.rs | 1 - src/libsyntax_ext/deriving/debug.rs | 1 - src/libsyntax_ext/deriving/decodable.rs | 1 - src/libsyntax_ext/deriving/default.rs | 1 - src/libsyntax_ext/deriving/encodable.rs | 1 - src/libsyntax_ext/deriving/generic/mod.rs | 1 - src/libsyntax_ext/deriving/generic/ty.rs | 1 - src/libsyntax_ext/deriving/hash.rs | 1 - src/libsyntax_ext/deriving/mod.rs | 1 - src/libsyntax_ext/env.rs | 1 - src/libsyntax_ext/format.rs | 1 - src/libsyntax_ext/global_allocator.rs | 1 - src/libsyntax_ext/proc_macro_harness.rs | 1 - src/libsyntax_ext/source_util.rs | 1 - src/libsyntax_ext/test.rs | 1 - src/libsyntax_ext/test_harness.rs | 1 - src/test/ui-fulldeps/auxiliary/plugin-args.rs | 1 - .../ui-fulldeps/auxiliary/roman-numerals.rs | 1 - 30 files changed, 130 insertions(+), 435 deletions(-) diff --git a/src/doc/unstable-book/src/language-features/plugin.md b/src/doc/unstable-book/src/language-features/plugin.md index f19b39daca3ef..8be4d16998276 100644 --- a/src/doc/unstable-book/src/language-features/plugin.md +++ b/src/doc/unstable-book/src/language-features/plugin.md @@ -59,7 +59,6 @@ extern crate rustc_plugin; use syntax::parse::token::{self, Token}; use syntax::tokenstream::TokenTree; use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; -use syntax::ext::build::AstBuilder; // A trait for expr_usize. use syntax_pos::Span; use rustc_plugin::Registry; @@ -164,13 +163,6 @@ can continue and find further errors. To print syntax fragments for debugging, you can use `span_note` together with `syntax::print::pprust::*_to_string`. -The example above produced an integer literal using `AstBuilder::expr_usize`. -As an alternative to the `AstBuilder` trait, `libsyntax` provides a set of -quasiquote macros. They are undocumented and very rough around the edges. -However, the implementation may be a good starting point for an improved -quasiquote as an ordinary plugin library. - - # Lint plugins Plugins can extend [Rust's lint diff --git a/src/libsyntax/attr/builtin.rs b/src/libsyntax/attr/builtin.rs index eabb6302d463b..5fb513783fbaa 100644 --- a/src/libsyntax/attr/builtin.rs +++ b/src/libsyntax/attr/builtin.rs @@ -3,7 +3,6 @@ use crate::ast::{self, Attribute, MetaItem, NestedMetaItem}; use crate::early_buffered_lints::BufferedEarlyLintId; use crate::ext::base::ExtCtxt; -use crate::ext::build::AstBuilder; use crate::feature_gate::{Features, GatedCfg}; use crate::parse::ParseSess; diff --git a/src/libsyntax/diagnostics/plugin.rs b/src/libsyntax/diagnostics/plugin.rs index e5e55a6444a2e..80591ad304df0 100644 --- a/src/libsyntax/diagnostics/plugin.rs +++ b/src/libsyntax/diagnostics/plugin.rs @@ -4,7 +4,6 @@ use std::env; use crate::ast::{self, Ident, Name}; use crate::source_map; use crate::ext::base::{ExtCtxt, MacEager, MacResult}; -use crate::ext::build::AstBuilder; use crate::parse::token::{self, Token}; use crate::ptr::P; use crate::symbol::kw; diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 0791dc94e34b2..570ca012364f6 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -9,295 +9,20 @@ use crate::ThinVec; use rustc_target::spec::abi::Abi; use syntax_pos::{Pos, Span}; -pub trait AstBuilder { - // Paths - fn path(&self, span: Span, strs: Vec ) -> ast::Path; - fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path; - fn path_global(&self, span: Span, strs: Vec ) -> ast::Path; - fn path_all(&self, sp: Span, - global: bool, - idents: Vec, - args: Vec, - constraints: Vec) - -> ast::Path; - - fn qpath(&self, self_type: P, - trait_path: ast::Path, - ident: ast::Ident) - -> (ast::QSelf, ast::Path); - fn qpath_all(&self, self_type: P, - trait_path: ast::Path, - ident: ast::Ident, - args: Vec, - constraints: Vec) - -> (ast::QSelf, ast::Path); - - // types and consts - fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy; - - fn ty(&self, span: Span, ty: ast::TyKind) -> P; - fn ty_path(&self, path: ast::Path) -> P; - fn ty_ident(&self, span: Span, idents: ast::Ident) -> P; - fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst; - fn const_ident(&self, span: Span, idents: ast::Ident) -> ast::AnonConst; - - fn ty_rptr(&self, span: Span, - ty: P, - lifetime: Option, - mutbl: ast::Mutability) -> P; - fn ty_ptr(&self, span: Span, - ty: P, - mutbl: ast::Mutability) -> P; - - fn ty_infer(&self, sp: Span) -> P; - - fn typaram(&self, - span: Span, - id: ast::Ident, - attrs: Vec, - bounds: ast::GenericBounds, - default: Option>) -> ast::GenericParam; - - fn trait_ref(&self, path: ast::Path) -> ast::TraitRef; - fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef; - fn trait_bound(&self, path: ast::Path) -> ast::GenericBound; - fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime; - fn lifetime_def(&self, - span: Span, - ident: ast::Ident, - attrs: Vec, - bounds: ast::GenericBounds) - -> ast::GenericParam; - - // Statements - fn stmt_expr(&self, expr: P) -> ast::Stmt; - fn stmt_semi(&self, expr: P) -> ast::Stmt; - fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P) -> ast::Stmt; - fn stmt_let_typed(&self, - sp: Span, - mutbl: bool, - ident: ast::Ident, - typ: P, - ex: P) - -> ast::Stmt; - fn stmt_let_type_only(&self, span: Span, ty: P) -> ast::Stmt; - fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt; - - // Blocks - fn block(&self, span: Span, stmts: Vec) -> P; - fn block_expr(&self, expr: P) -> P; - - // Expressions - fn expr(&self, span: Span, node: ast::ExprKind) -> P; - fn expr_path(&self, path: ast::Path) -> P; - fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P; - fn expr_ident(&self, span: Span, id: ast::Ident) -> P; - - fn expr_self(&self, span: Span) -> P; - fn expr_binary(&self, sp: Span, op: ast::BinOpKind, - lhs: P, rhs: P) -> P; - fn expr_deref(&self, sp: Span, e: P) -> P; - fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P) -> P; - - fn expr_addr_of(&self, sp: Span, e: P) -> P; - fn expr_mut_addr_of(&self, sp: Span, e: P) -> P; - fn expr_field_access(&self, span: Span, expr: P, ident: ast::Ident) -> P; - fn expr_tup_field_access(&self, sp: Span, expr: P, - idx: usize) -> P; - fn expr_call(&self, span: Span, expr: P, args: Vec>) -> P; - fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec>) -> P; - fn expr_call_global(&self, sp: Span, fn_path: Vec, - args: Vec> ) -> P; - fn expr_method_call(&self, span: Span, - expr: P, ident: ast::Ident, - args: Vec> ) -> P; - fn expr_block(&self, b: P) -> P; - fn expr_cast(&self, sp: Span, expr: P, ty: P) -> P; - - fn field_imm(&self, span: Span, name: Ident, e: P) -> ast::Field; - fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec) -> P; - fn expr_struct_ident(&self, span: Span, id: ast::Ident, - fields: Vec) -> P; - - fn expr_lit(&self, sp: Span, lit: ast::LitKind) -> P; - - fn expr_usize(&self, span: Span, i: usize) -> P; - fn expr_isize(&self, sp: Span, i: isize) -> P; - fn expr_u8(&self, sp: Span, u: u8) -> P; - fn expr_u16(&self, sp: Span, u: u16) -> P; - fn expr_u32(&self, sp: Span, u: u32) -> P; - fn expr_bool(&self, sp: Span, value: bool) -> P; - - fn expr_vec(&self, sp: Span, exprs: Vec>) -> P; - fn expr_vec_ng(&self, sp: Span) -> P; - fn expr_vec_slice(&self, sp: Span, exprs: Vec>) -> P; - fn expr_str(&self, sp: Span, s: Symbol) -> P; - - fn expr_some(&self, sp: Span, expr: P) -> P; - fn expr_none(&self, sp: Span) -> P; - - fn expr_break(&self, sp: Span) -> P; - - fn expr_tuple(&self, sp: Span, exprs: Vec>) -> P; - - fn expr_fail(&self, span: Span, msg: Symbol) -> P; - fn expr_unreachable(&self, span: Span) -> P; - - fn expr_ok(&self, span: Span, expr: P) -> P; - fn expr_err(&self, span: Span, expr: P) -> P; - fn expr_try(&self, span: Span, head: P) -> P; - - fn pat(&self, span: Span, pat: PatKind) -> P; - fn pat_wild(&self, span: Span) -> P; - fn pat_lit(&self, span: Span, expr: P) -> P; - fn pat_ident(&self, span: Span, ident: ast::Ident) -> P; - - fn pat_ident_binding_mode(&self, - span: Span, - ident: ast::Ident, - bm: ast::BindingMode) -> P; - fn pat_path(&self, span: Span, path: ast::Path) -> P; - fn pat_tuple_struct(&self, span: Span, path: ast::Path, - subpats: Vec>) -> P; - fn pat_struct(&self, span: Span, path: ast::Path, - field_pats: Vec>) -> P; - fn pat_tuple(&self, span: Span, pats: Vec>) -> P; - - fn pat_some(&self, span: Span, pat: P) -> P; - fn pat_none(&self, span: Span) -> P; - - fn pat_ok(&self, span: Span, pat: P) -> P; - fn pat_err(&self, span: Span, pat: P) -> P; - - fn arm(&self, span: Span, pats: Vec>, expr: P) -> ast::Arm; - fn arm_unreachable(&self, span: Span) -> ast::Arm; - - fn expr_match(&self, span: Span, arg: P, arms: Vec ) -> P; - fn expr_if(&self, span: Span, - cond: P, then: P, els: Option>) -> P; - fn expr_loop(&self, span: Span, block: P) -> P; - - fn lambda_fn_decl(&self, - span: Span, - fn_decl: P, - body: P, - fn_decl_span: Span) - -> P; - - fn lambda(&self, span: Span, ids: Vec, body: P) -> P; - fn lambda0(&self, span: Span, body: P) -> P; - fn lambda1(&self, span: Span, body: P, ident: ast::Ident) -> P; - - fn lambda_stmts(&self, span: Span, ids: Vec, - blk: Vec) -> P; - fn lambda_stmts_0(&self, span: Span, stmts: Vec) -> P; - fn lambda_stmts_1(&self, span: Span, stmts: Vec, - ident: ast::Ident) -> P; - - // Items - fn item(&self, span: Span, - name: Ident, attrs: Vec , node: ast::ItemKind) -> P; - - fn arg(&self, span: Span, name: Ident, ty: P) -> ast::Arg; - // FIXME: unused `self` - fn fn_decl(&self, inputs: Vec , output: ast::FunctionRetTy) -> P; - - fn item_fn_poly(&self, - span: Span, - name: Ident, - inputs: Vec , - output: P, - generics: Generics, - body: P) -> P; - fn item_fn(&self, - span: Span, - name: Ident, - inputs: Vec , - output: P, - body: P) -> P; - - fn variant(&self, span: Span, name: Ident, tys: Vec> ) -> ast::Variant; - fn item_enum_poly(&self, - span: Span, - name: Ident, - enum_definition: ast::EnumDef, - generics: Generics) -> P; - fn item_enum(&self, span: Span, name: Ident, enum_def: ast::EnumDef) -> P; - - fn item_struct_poly(&self, - span: Span, - name: Ident, - struct_def: ast::VariantData, - generics: Generics) -> P; - fn item_struct(&self, span: Span, name: Ident, struct_def: ast::VariantData) -> P; - - fn item_mod(&self, span: Span, inner_span: Span, - name: Ident, attrs: Vec, - items: Vec>) -> P; - - fn item_extern_crate(&self, span: Span, name: Ident) -> P; - - fn item_static(&self, - span: Span, - name: Ident, - ty: P, - mutbl: ast::Mutability, - expr: P) - -> P; - - fn item_const(&self, - span: Span, - name: Ident, - ty: P, - expr: P) - -> P; - - fn item_ty_poly(&self, - span: Span, - name: Ident, - ty: P, - generics: Generics) -> P; - fn item_ty(&self, span: Span, name: Ident, ty: P) -> P; - - fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute; - - fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem; - - fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem; - - fn meta_list(&self, - sp: Span, - name: ast::Name, - mis: Vec ) - -> ast::MetaItem; - fn meta_name_value(&self, - sp: Span, - name: ast::Name, - value: ast::LitKind) - -> ast::MetaItem; - - fn item_use(&self, sp: Span, - vis: ast::Visibility, vp: P) -> P; - fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P; - fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, - ident: Option, path: ast::Path) -> P; - fn item_use_list(&self, sp: Span, vis: ast::Visibility, - path: Vec, imports: &[ast::Ident]) -> P; - fn item_use_glob(&self, sp: Span, - vis: ast::Visibility, path: Vec) -> P; -} +// Left so that Cargo tests don't break, this can be removed once those no longer use it +pub trait AstBuilder {} -impl<'a> AstBuilder for ExtCtxt<'a> { - fn path(&self, span: Span, strs: Vec ) -> ast::Path { +impl<'a> ExtCtxt<'a> { + pub fn path(&self, span: Span, strs: Vec ) -> ast::Path { self.path_all(span, false, strs, vec![], vec![]) } - fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path { + pub fn path_ident(&self, span: Span, id: ast::Ident) -> ast::Path { self.path(span, vec![id]) } - fn path_global(&self, span: Span, strs: Vec ) -> ast::Path { + pub fn path_global(&self, span: Span, strs: Vec ) -> ast::Path { self.path_all(span, true, strs, vec![], vec![]) } - fn path_all(&self, + pub fn path_all(&self, span: Span, global: bool, mut idents: Vec , @@ -330,7 +55,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { /// Constructs a qualified path. /// /// Constructs a path like `::ident`. - fn qpath(&self, + pub fn qpath(&self, self_type: P, trait_path: ast::Path, ident: ast::Ident) @@ -341,7 +66,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { /// Constructs a qualified path. /// /// Constructs a path like `::ident<'a, T, A = Bar>`. - fn qpath_all(&self, + pub fn qpath_all(&self, self_type: P, trait_path: ast::Path, ident: ast::Ident, @@ -363,14 +88,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }, path) } - fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy { + pub fn ty_mt(&self, ty: P, mutbl: ast::Mutability) -> ast::MutTy { ast::MutTy { ty, mutbl, } } - fn ty(&self, span: Span, ty: ast::TyKind) -> P { + pub fn ty(&self, span: Span, ty: ast::TyKind) -> P { P(ast::Ty { id: ast::DUMMY_NODE_ID, span, @@ -378,18 +103,18 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn ty_path(&self, path: ast::Path) -> P { + pub fn ty_path(&self, path: ast::Path) -> P { self.ty(path.span, ast::TyKind::Path(None, path)) } // Might need to take bounds as an argument in the future, if you ever want // to generate a bounded existential trait type. - fn ty_ident(&self, span: Span, ident: ast::Ident) + pub fn ty_ident(&self, span: Span, ident: ast::Ident) -> P { self.ty_path(self.path_ident(span, ident)) } - fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst { + pub fn anon_const(&self, span: Span, expr: ast::ExprKind) -> ast::AnonConst { ast::AnonConst { id: ast::DUMMY_NODE_ID, value: P(ast::Expr { @@ -401,11 +126,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn const_ident(&self, span: Span, ident: ast::Ident) -> ast::AnonConst { + pub fn const_ident(&self, span: Span, ident: ast::Ident) -> ast::AnonConst { self.anon_const(span, ast::ExprKind::Path(None, self.path_ident(span, ident))) } - fn ty_rptr(&self, + pub fn ty_rptr(&self, span: Span, ty: P, lifetime: Option, @@ -415,7 +140,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ast::TyKind::Rptr(lifetime, self.ty_mt(ty, mutbl))) } - fn ty_ptr(&self, + pub fn ty_ptr(&self, span: Span, ty: P, mutbl: ast::Mutability) @@ -424,11 +149,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ast::TyKind::Ptr(self.ty_mt(ty, mutbl))) } - fn ty_infer(&self, span: Span) -> P { + pub fn ty_infer(&self, span: Span) -> P { self.ty(span, ast::TyKind::Infer) } - fn typaram(&self, + pub fn typaram(&self, span: Span, ident: ast::Ident, attrs: Vec, @@ -445,14 +170,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { + pub fn trait_ref(&self, path: ast::Path) -> ast::TraitRef { ast::TraitRef { path, ref_id: ast::DUMMY_NODE_ID, } } - fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { + pub fn poly_trait_ref(&self, span: Span, path: ast::Path) -> ast::PolyTraitRef { ast::PolyTraitRef { bound_generic_params: Vec::new(), trait_ref: self.trait_ref(path), @@ -460,16 +185,16 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn trait_bound(&self, path: ast::Path) -> ast::GenericBound { + pub fn trait_bound(&self, path: ast::Path) -> ast::GenericBound { ast::GenericBound::Trait(self.poly_trait_ref(path.span, path), ast::TraitBoundModifier::None) } - fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime { + pub fn lifetime(&self, span: Span, ident: ast::Ident) -> ast::Lifetime { ast::Lifetime { id: ast::DUMMY_NODE_ID, ident: ident.with_span_pos(span) } } - fn lifetime_def(&self, + pub fn lifetime_def(&self, span: Span, ident: ast::Ident, attrs: Vec, @@ -485,7 +210,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_expr(&self, expr: P) -> ast::Stmt { + pub fn stmt_expr(&self, expr: P) -> ast::Stmt { ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, @@ -493,7 +218,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_semi(&self, expr: P) -> ast::Stmt { + pub fn stmt_semi(&self, expr: P) -> ast::Stmt { ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, @@ -501,7 +226,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, + pub fn stmt_let(&self, sp: Span, mutbl: bool, ident: ast::Ident, ex: P) -> ast::Stmt { let pat = if mutbl { let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Mutable); @@ -524,7 +249,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_let_typed(&self, + pub fn stmt_let_typed(&self, sp: Span, mutbl: bool, ident: ast::Ident, @@ -553,7 +278,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } // Generates `let _: Type;`, which is usually used for type assertions. - fn stmt_let_type_only(&self, span: Span, ty: P) -> ast::Stmt { + pub fn stmt_let_type_only(&self, span: Span, ty: P) -> ast::Stmt { let local = P(ast::Local { pat: self.pat_wild(span), ty: Some(ty), @@ -569,7 +294,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt { + pub fn stmt_item(&self, sp: Span, item: P) -> ast::Stmt { ast::Stmt { id: ast::DUMMY_NODE_ID, node: ast::StmtKind::Item(item), @@ -577,14 +302,14 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn block_expr(&self, expr: P) -> P { + pub fn block_expr(&self, expr: P) -> P { self.block(expr.span, vec![ast::Stmt { id: ast::DUMMY_NODE_ID, span: expr.span, node: ast::StmtKind::Expr(expr), }]) } - fn block(&self, span: Span, stmts: Vec) -> P { + pub fn block(&self, span: Span, stmts: Vec) -> P { P(ast::Block { stmts, id: ast::DUMMY_NODE_ID, @@ -593,7 +318,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn expr(&self, span: Span, node: ast::ExprKind) -> P { + pub fn expr(&self, span: Span, node: ast::ExprKind) -> P { P(ast::Expr { id: ast::DUMMY_NODE_ID, node, @@ -602,61 +327,65 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn expr_path(&self, path: ast::Path) -> P { + pub fn expr_path(&self, path: ast::Path) -> P { self.expr(path.span, ast::ExprKind::Path(None, path)) } /// Constructs a `QPath` expression. - fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P { + pub fn expr_qpath(&self, span: Span, qself: ast::QSelf, path: ast::Path) -> P { self.expr(span, ast::ExprKind::Path(Some(qself), path)) } - fn expr_ident(&self, span: Span, id: ast::Ident) -> P { + pub fn expr_ident(&self, span: Span, id: ast::Ident) -> P { self.expr_path(self.path_ident(span, id)) } - fn expr_self(&self, span: Span) -> P { + pub fn expr_self(&self, span: Span) -> P { self.expr_ident(span, Ident::with_empty_ctxt(kw::SelfLower)) } - fn expr_binary(&self, sp: Span, op: ast::BinOpKind, + pub fn expr_binary(&self, sp: Span, op: ast::BinOpKind, lhs: P, rhs: P) -> P { self.expr(sp, ast::ExprKind::Binary(Spanned { node: op, span: sp }, lhs, rhs)) } - fn expr_deref(&self, sp: Span, e: P) -> P { + pub fn expr_deref(&self, sp: Span, e: P) -> P { self.expr_unary(sp, UnOp::Deref, e) } - fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P) -> P { + pub fn expr_unary(&self, sp: Span, op: ast::UnOp, e: P) -> P { self.expr(sp, ast::ExprKind::Unary(op, e)) } - fn expr_field_access(&self, sp: Span, expr: P, ident: ast::Ident) -> P { + pub fn expr_field_access( + &self, sp: Span, expr: P, ident: ast::Ident, + ) -> P { self.expr(sp, ast::ExprKind::Field(expr, ident.with_span_pos(sp))) } - fn expr_tup_field_access(&self, sp: Span, expr: P, idx: usize) -> P { + pub fn expr_tup_field_access(&self, sp: Span, expr: P, idx: usize) -> P { let ident = Ident::from_str(&idx.to_string()).with_span_pos(sp); self.expr(sp, ast::ExprKind::Field(expr, ident)) } - fn expr_addr_of(&self, sp: Span, e: P) -> P { + pub fn expr_addr_of(&self, sp: Span, e: P) -> P { self.expr(sp, ast::ExprKind::AddrOf(ast::Mutability::Immutable, e)) } - fn expr_mut_addr_of(&self, sp: Span, e: P) -> P { + pub fn expr_mut_addr_of(&self, sp: Span, e: P) -> P { self.expr(sp, ast::ExprKind::AddrOf(ast::Mutability::Mutable, e)) } - fn expr_call(&self, span: Span, expr: P, args: Vec>) -> P { + pub fn expr_call( + &self, span: Span, expr: P, args: Vec>, + ) -> P { self.expr(span, ast::ExprKind::Call(expr, args)) } - fn expr_call_ident(&self, span: Span, id: ast::Ident, + pub fn expr_call_ident(&self, span: Span, id: ast::Ident, args: Vec>) -> P { self.expr(span, ast::ExprKind::Call(self.expr_ident(span, id), args)) } - fn expr_call_global(&self, sp: Span, fn_path: Vec , + pub fn expr_call_global(&self, sp: Span, fn_path: Vec , args: Vec> ) -> P { let pathexpr = self.expr_path(self.path_global(sp, fn_path)); self.expr_call(sp, pathexpr, args) } - fn expr_method_call(&self, span: Span, + pub fn expr_method_call(&self, span: Span, expr: P, ident: ast::Ident, mut args: Vec> ) -> P { @@ -664,10 +393,10 @@ impl<'a> AstBuilder for ExtCtxt<'a> { let segment = ast::PathSegment::from_ident(ident.with_span_pos(span)); self.expr(span, ast::ExprKind::MethodCall(segment, args)) } - fn expr_block(&self, b: P) -> P { + pub fn expr_block(&self, b: P) -> P { self.expr(b.span, ast::ExprKind::Block(b, None)) } - fn field_imm(&self, span: Span, ident: Ident, e: P) -> ast::Field { + pub fn field_imm(&self, span: Span, ident: Ident, e: P) -> ast::Field { ast::Field { ident: ident.with_span_pos(span), expr: e, @@ -676,23 +405,25 @@ impl<'a> AstBuilder for ExtCtxt<'a> { attrs: ThinVec::new(), } } - fn expr_struct(&self, span: Span, path: ast::Path, fields: Vec) -> P { + pub fn expr_struct( + &self, span: Span, path: ast::Path, fields: Vec + ) -> P { self.expr(span, ast::ExprKind::Struct(path, fields, None)) } - fn expr_struct_ident(&self, span: Span, + pub fn expr_struct_ident(&self, span: Span, id: ast::Ident, fields: Vec) -> P { self.expr_struct(span, self.path_ident(span, id), fields) } - fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P { + pub fn expr_lit(&self, span: Span, lit_kind: ast::LitKind) -> P { let lit = ast::Lit::from_lit_kind(lit_kind, span); self.expr(span, ast::ExprKind::Lit(lit)) } - fn expr_usize(&self, span: Span, i: usize) -> P { + pub fn expr_usize(&self, span: Span, i: usize) -> P { self.expr_lit(span, ast::LitKind::Int(i as u128, ast::LitIntType::Unsigned(ast::UintTy::Usize))) } - fn expr_isize(&self, sp: Span, i: isize) -> P { + pub fn expr_isize(&self, sp: Span, i: isize) -> P { if i < 0 { let i = (-i) as u128; let lit_ty = ast::LitIntType::Signed(ast::IntTy::Isize); @@ -703,59 +434,59 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ast::LitIntType::Signed(ast::IntTy::Isize))) } } - fn expr_u32(&self, sp: Span, u: u32) -> P { + pub fn expr_u32(&self, sp: Span, u: u32) -> P { self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U32))) } - fn expr_u16(&self, sp: Span, u: u16) -> P { + pub fn expr_u16(&self, sp: Span, u: u16) -> P { self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U16))) } - fn expr_u8(&self, sp: Span, u: u8) -> P { + pub fn expr_u8(&self, sp: Span, u: u8) -> P { self.expr_lit(sp, ast::LitKind::Int(u as u128, ast::LitIntType::Unsigned(ast::UintTy::U8))) } - fn expr_bool(&self, sp: Span, value: bool) -> P { + pub fn expr_bool(&self, sp: Span, value: bool) -> P { self.expr_lit(sp, ast::LitKind::Bool(value)) } - fn expr_vec(&self, sp: Span, exprs: Vec>) -> P { + pub fn expr_vec(&self, sp: Span, exprs: Vec>) -> P { self.expr(sp, ast::ExprKind::Array(exprs)) } - fn expr_vec_ng(&self, sp: Span) -> P { + pub fn expr_vec_ng(&self, sp: Span) -> P { self.expr_call_global(sp, self.std_path(&[sym::vec, sym::Vec, sym::new]), Vec::new()) } - fn expr_vec_slice(&self, sp: Span, exprs: Vec>) -> P { + pub fn expr_vec_slice(&self, sp: Span, exprs: Vec>) -> P { self.expr_addr_of(sp, self.expr_vec(sp, exprs)) } - fn expr_str(&self, sp: Span, s: Symbol) -> P { + pub fn expr_str(&self, sp: Span, s: Symbol) -> P { self.expr_lit(sp, ast::LitKind::Str(s, ast::StrStyle::Cooked)) } - fn expr_cast(&self, sp: Span, expr: P, ty: P) -> P { + pub fn expr_cast(&self, sp: Span, expr: P, ty: P) -> P { self.expr(sp, ast::ExprKind::Cast(expr, ty)) } - fn expr_some(&self, sp: Span, expr: P) -> P { + pub fn expr_some(&self, sp: Span, expr: P) -> P { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); self.expr_call_global(sp, some, vec![expr]) } - fn expr_none(&self, sp: Span) -> P { + pub fn expr_none(&self, sp: Span) -> P { let none = self.std_path(&[sym::option, sym::Option, sym::None]); let none = self.path_global(sp, none); self.expr_path(none) } - fn expr_break(&self, sp: Span) -> P { + pub fn expr_break(&self, sp: Span) -> P { self.expr(sp, ast::ExprKind::Break(None, None)) } - fn expr_tuple(&self, sp: Span, exprs: Vec>) -> P { + pub fn expr_tuple(&self, sp: Span, exprs: Vec>) -> P { self.expr(sp, ast::ExprKind::Tup(exprs)) } - fn expr_fail(&self, span: Span, msg: Symbol) -> P { + pub fn expr_fail(&self, span: Span, msg: Symbol) -> P { let loc = self.source_map().lookup_char_pos(span.lo()); let expr_file = self.expr_str(span, Symbol::intern(&loc.file.name.to_string())); let expr_line = self.expr_u32(span, loc.line as u32); @@ -770,21 +501,21 @@ impl<'a> AstBuilder for ExtCtxt<'a> { expr_loc_ptr]) } - fn expr_unreachable(&self, span: Span) -> P { + pub fn expr_unreachable(&self, span: Span) -> P { self.expr_fail(span, Symbol::intern("internal error: entered unreachable code")) } - fn expr_ok(&self, sp: Span, expr: P) -> P { + pub fn expr_ok(&self, sp: Span, expr: P) -> P { let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); self.expr_call_global(sp, ok, vec![expr]) } - fn expr_err(&self, sp: Span, expr: P) -> P { + pub fn expr_err(&self, sp: Span, expr: P) -> P { let err = self.std_path(&[sym::result, sym::Result, sym::Err]); self.expr_call_global(sp, err, vec![expr]) } - fn expr_try(&self, sp: Span, head: P) -> P { + pub fn expr_try(&self, sp: Span, head: P) -> P { let ok = self.std_path(&[sym::result, sym::Result, sym::Ok]); let ok_path = self.path_global(sp, ok); let err = self.std_path(&[sym::result, sym::Result, sym::Err]); @@ -814,67 +545,67 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } - fn pat(&self, span: Span, pat: PatKind) -> P { + pub fn pat(&self, span: Span, pat: PatKind) -> P { P(ast::Pat { id: ast::DUMMY_NODE_ID, node: pat, span }) } - fn pat_wild(&self, span: Span) -> P { + pub fn pat_wild(&self, span: Span) -> P { self.pat(span, PatKind::Wild) } - fn pat_lit(&self, span: Span, expr: P) -> P { + pub fn pat_lit(&self, span: Span, expr: P) -> P { self.pat(span, PatKind::Lit(expr)) } - fn pat_ident(&self, span: Span, ident: ast::Ident) -> P { + pub fn pat_ident(&self, span: Span, ident: ast::Ident) -> P { let binding_mode = ast::BindingMode::ByValue(ast::Mutability::Immutable); self.pat_ident_binding_mode(span, ident, binding_mode) } - fn pat_ident_binding_mode(&self, + pub fn pat_ident_binding_mode(&self, span: Span, ident: ast::Ident, bm: ast::BindingMode) -> P { let pat = PatKind::Ident(bm, ident.with_span_pos(span), None); self.pat(span, pat) } - fn pat_path(&self, span: Span, path: ast::Path) -> P { + pub fn pat_path(&self, span: Span, path: ast::Path) -> P { self.pat(span, PatKind::Path(None, path)) } - fn pat_tuple_struct(&self, span: Span, path: ast::Path, + pub fn pat_tuple_struct(&self, span: Span, path: ast::Path, subpats: Vec>) -> P { self.pat(span, PatKind::TupleStruct(path, subpats)) } - fn pat_struct(&self, span: Span, path: ast::Path, + pub fn pat_struct(&self, span: Span, path: ast::Path, field_pats: Vec>) -> P { self.pat(span, PatKind::Struct(path, field_pats, false)) } - fn pat_tuple(&self, span: Span, pats: Vec>) -> P { + pub fn pat_tuple(&self, span: Span, pats: Vec>) -> P { self.pat(span, PatKind::Tuple(pats)) } - fn pat_some(&self, span: Span, pat: P) -> P { + pub fn pat_some(&self, span: Span, pat: P) -> P { let some = self.std_path(&[sym::option, sym::Option, sym::Some]); let path = self.path_global(span, some); self.pat_tuple_struct(span, path, vec![pat]) } - fn pat_none(&self, span: Span) -> P { + pub fn pat_none(&self, span: Span) -> P { let some = self.std_path(&[sym::option, sym::Option, sym::None]); let path = self.path_global(span, some); self.pat_path(span, path) } - fn pat_ok(&self, span: Span, pat: P) -> P { + pub fn pat_ok(&self, span: Span, pat: P) -> P { let some = self.std_path(&[sym::result, sym::Result, sym::Ok]); let path = self.path_global(span, some); self.pat_tuple_struct(span, path, vec![pat]) } - fn pat_err(&self, span: Span, pat: P) -> P { + pub fn pat_err(&self, span: Span, pat: P) -> P { let some = self.std_path(&[sym::result, sym::Result, sym::Err]); let path = self.path_global(span, some); self.pat_tuple_struct(span, path, vec![pat]) } - fn arm(&self, span: Span, pats: Vec>, expr: P) -> ast::Arm { + pub fn arm(&self, span: Span, pats: Vec>, expr: P) -> ast::Arm { ast::Arm { attrs: vec![], pats, @@ -884,25 +615,25 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } } - fn arm_unreachable(&self, span: Span) -> ast::Arm { + pub fn arm_unreachable(&self, span: Span) -> ast::Arm { self.arm(span, vec![self.pat_wild(span)], self.expr_unreachable(span)) } - fn expr_match(&self, span: Span, arg: P, arms: Vec) -> P { + pub fn expr_match(&self, span: Span, arg: P, arms: Vec) -> P { self.expr(span, ast::ExprKind::Match(arg, arms)) } - fn expr_if(&self, span: Span, cond: P, + pub fn expr_if(&self, span: Span, cond: P, then: P, els: Option>) -> P { let els = els.map(|x| self.expr_block(self.block_expr(x))); self.expr(span, ast::ExprKind::If(cond, self.block_expr(then), els)) } - fn expr_loop(&self, span: Span, block: P) -> P { + pub fn expr_loop(&self, span: Span, block: P) -> P { self.expr(span, ast::ExprKind::Loop(block, None)) } - fn lambda_fn_decl(&self, + pub fn lambda_fn_decl(&self, span: Span, fn_decl: P, body: P, @@ -916,7 +647,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { fn_decl_span)) } - fn lambda(&self, + pub fn lambda(&self, span: Span, ids: Vec, body: P) @@ -937,30 +668,30 @@ impl<'a> AstBuilder for ExtCtxt<'a> { span)) } - fn lambda0(&self, span: Span, body: P) -> P { + pub fn lambda0(&self, span: Span, body: P) -> P { self.lambda(span, Vec::new(), body) } - fn lambda1(&self, span: Span, body: P, ident: ast::Ident) -> P { + pub fn lambda1(&self, span: Span, body: P, ident: ast::Ident) -> P { self.lambda(span, vec![ident], body) } - fn lambda_stmts(&self, + pub fn lambda_stmts(&self, span: Span, ids: Vec, stmts: Vec) -> P { self.lambda(span, ids, self.expr_block(self.block(span, stmts))) } - fn lambda_stmts_0(&self, span: Span, stmts: Vec) -> P { + pub fn lambda_stmts_0(&self, span: Span, stmts: Vec) -> P { self.lambda0(span, self.expr_block(self.block(span, stmts))) } - fn lambda_stmts_1(&self, span: Span, stmts: Vec, + pub fn lambda_stmts_1(&self, span: Span, stmts: Vec, ident: ast::Ident) -> P { self.lambda1(span, self.expr_block(self.block(span, stmts)), ident) } - fn arg(&self, span: Span, ident: ast::Ident, ty: P) -> ast::Arg { + pub fn arg(&self, span: Span, ident: ast::Ident, ty: P) -> ast::Arg { let arg_pat = self.pat_ident(span, ident); ast::Arg { attrs: ThinVec::default(), @@ -972,7 +703,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { } // FIXME: unused `self` - fn fn_decl(&self, inputs: Vec, output: ast::FunctionRetTy) -> P { + pub fn fn_decl(&self, inputs: Vec, output: ast::FunctionRetTy) -> P { P(ast::FnDecl { inputs, output, @@ -980,7 +711,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn item(&self, span: Span, name: Ident, + pub fn item(&self, span: Span, name: Ident, attrs: Vec, node: ast::ItemKind) -> P { // FIXME: Would be nice if our generated code didn't violate // Rust coding conventions @@ -995,7 +726,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn item_fn_poly(&self, + pub fn item_fn_poly(&self, span: Span, name: Ident, inputs: Vec , @@ -1016,7 +747,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { body)) } - fn item_fn(&self, + pub fn item_fn(&self, span: Span, name: Ident, inputs: Vec , @@ -1032,7 +763,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { body) } - fn variant(&self, span: Span, ident: Ident, tys: Vec> ) -> ast::Variant { + pub fn variant(&self, span: Span, ident: Ident, tys: Vec> ) -> ast::Variant { let fields: Vec<_> = tys.into_iter().map(|ty| { ast::StructField { span: ty.span, @@ -1060,19 +791,19 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn item_enum_poly(&self, span: Span, name: Ident, + pub fn item_enum_poly(&self, span: Span, name: Ident, enum_definition: ast::EnumDef, generics: Generics) -> P { self.item(span, name, Vec::new(), ast::ItemKind::Enum(enum_definition, generics)) } - fn item_enum(&self, span: Span, name: Ident, + pub fn item_enum(&self, span: Span, name: Ident, enum_definition: ast::EnumDef) -> P { self.item_enum_poly(span, name, enum_definition, Generics::default()) } - fn item_struct(&self, span: Span, name: Ident, + pub fn item_struct(&self, span: Span, name: Ident, struct_def: ast::VariantData) -> P { self.item_struct_poly( span, @@ -1082,12 +813,12 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ) } - fn item_struct_poly(&self, span: Span, name: Ident, + pub fn item_struct_poly(&self, span: Span, name: Ident, struct_def: ast::VariantData, generics: Generics) -> P { self.item(span, name, Vec::new(), ast::ItemKind::Struct(struct_def, generics)) } - fn item_mod(&self, span: Span, inner_span: Span, name: Ident, + pub fn item_mod(&self, span: Span, inner_span: Span, name: Ident, attrs: Vec, items: Vec>) -> P { self.item( @@ -1102,11 +833,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { ) } - fn item_extern_crate(&self, span: Span, name: Ident) -> P { + pub fn item_extern_crate(&self, span: Span, name: Ident) -> P { self.item(span, name, Vec::new(), ast::ItemKind::ExternCrate(None)) } - fn item_static(&self, + pub fn item_static(&self, span: Span, name: Ident, ty: P, @@ -1116,7 +847,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.item(span, name, Vec::new(), ast::ItemKind::Static(ty, mutbl, expr)) } - fn item_const(&self, + pub fn item_const(&self, span: Span, name: Ident, ty: P, @@ -1125,39 +856,39 @@ impl<'a> AstBuilder for ExtCtxt<'a> { self.item(span, name, Vec::new(), ast::ItemKind::Const(ty, expr)) } - fn item_ty_poly(&self, span: Span, name: Ident, ty: P, + pub fn item_ty_poly(&self, span: Span, name: Ident, ty: P, generics: Generics) -> P { self.item(span, name, Vec::new(), ast::ItemKind::Ty(ty, generics)) } - fn item_ty(&self, span: Span, name: Ident, ty: P) -> P { + pub fn item_ty(&self, span: Span, name: Ident, ty: P) -> P { self.item_ty_poly(span, name, ty, Generics::default()) } - fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { + pub fn attribute(&self, mi: ast::MetaItem) -> ast::Attribute { attr::mk_attr_outer(mi) } - fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem { + pub fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem { attr::mk_word_item(Ident::with_empty_ctxt(w).with_span_pos(sp)) } - fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem { + pub fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem { attr::mk_nested_word_item(Ident::with_empty_ctxt(w).with_span_pos(sp)) } - fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec) + pub fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec) -> ast::MetaItem { attr::mk_list_item(sp, Ident::with_empty_ctxt(name).with_span_pos(sp), mis) } - fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind) + pub fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind) -> ast::MetaItem { attr::mk_name_value_item(span, Ident::with_empty_ctxt(name).with_span_pos(span), lit_kind, span) } - fn item_use(&self, sp: Span, + pub fn item_use(&self, sp: Span, vis: ast::Visibility, vp: P) -> P { P(ast::Item { id: ast::DUMMY_NODE_ID, @@ -1170,11 +901,11 @@ impl<'a> AstBuilder for ExtCtxt<'a> { }) } - fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P { + pub fn item_use_simple(&self, sp: Span, vis: ast::Visibility, path: ast::Path) -> P { self.item_use_simple_(sp, vis, None, path) } - fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, + pub fn item_use_simple_(&self, sp: Span, vis: ast::Visibility, rename: Option, path: ast::Path) -> P { self.item_use(sp, vis, P(ast::UseTree { span: sp, @@ -1183,7 +914,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { })) } - fn item_use_list(&self, sp: Span, vis: ast::Visibility, + pub fn item_use_list(&self, sp: Span, vis: ast::Visibility, path: Vec, imports: &[ast::Ident]) -> P { let imports = imports.iter().map(|id| { (ast::UseTree { @@ -1200,7 +931,7 @@ impl<'a> AstBuilder for ExtCtxt<'a> { })) } - fn item_use_glob(&self, sp: Span, + pub fn item_use_glob(&self, sp: Span, vis: ast::Visibility, path: Vec) -> P { self.item_use(sp, vis, P(ast::UseTree { span: sp, diff --git a/src/libsyntax/ext/proc_macro.rs b/src/libsyntax/ext/proc_macro.rs index d1fabf963b5d9..ec708994fad86 100644 --- a/src/libsyntax/ext/proc_macro.rs +++ b/src/libsyntax/ext/proc_macro.rs @@ -2,7 +2,6 @@ use crate::ast::{self, ItemKind, Attribute, Mac}; use crate::attr::{mark_used, mark_known, HasAttrs}; use crate::errors::{Applicability, FatalError}; use crate::ext::base::{self, *}; -use crate::ext::build::AstBuilder; use crate::ext::proc_macro_server; use crate::parse::{self, token}; use crate::parse::parser::PathStyle; diff --git a/src/libsyntax_ext/assert.rs b/src/libsyntax_ext/assert.rs index 235565314f5e2..b10d8fcd357c4 100644 --- a/src/libsyntax_ext/assert.rs +++ b/src/libsyntax_ext/assert.rs @@ -3,7 +3,6 @@ use errors::{Applicability, DiagnosticBuilder}; use syntax::ast::{self, *}; use syntax::source_map::Spanned; use syntax::ext::base::*; -use syntax::ext::build::AstBuilder; use syntax::parse::token::{self, TokenKind}; use syntax::parse::parser::Parser; use syntax::print::pprust; diff --git a/src/libsyntax_ext/cfg.rs b/src/libsyntax_ext/cfg.rs index 2b64f558be0a0..84830e6ddda1a 100644 --- a/src/libsyntax_ext/cfg.rs +++ b/src/libsyntax_ext/cfg.rs @@ -6,7 +6,6 @@ use errors::DiagnosticBuilder; use syntax::ast; use syntax::ext::base::{self, *}; -use syntax::ext::build::AstBuilder; use syntax::attr; use syntax::tokenstream; use syntax::parse::token; diff --git a/src/libsyntax_ext/concat.rs b/src/libsyntax_ext/concat.rs index dbc985fd8599a..f1d079eb05379 100644 --- a/src/libsyntax_ext/concat.rs +++ b/src/libsyntax_ext/concat.rs @@ -1,6 +1,5 @@ use syntax::ast; use syntax::ext::base; -use syntax::ext::build::AstBuilder; use syntax::symbol::Symbol; use syntax::tokenstream; diff --git a/src/libsyntax_ext/deriving/clone.rs b/src/libsyntax_ext/deriving/clone.rs index 350eacc3230ef..2340238aaea41 100644 --- a/src/libsyntax_ext/deriving/clone.rs +++ b/src/libsyntax_ext/deriving/clone.rs @@ -5,7 +5,6 @@ use crate::deriving::generic::ty::*; use syntax::ast::{self, Expr, GenericArg, Generics, ItemKind, MetaItem, VariantData}; use syntax::attr; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::Span; diff --git a/src/libsyntax_ext/deriving/cmp/eq.rs b/src/libsyntax_ext/deriving/cmp/eq.rs index 5698a8e382391..0c34599814a79 100644 --- a/src/libsyntax_ext/deriving/cmp/eq.rs +++ b/src/libsyntax_ext/deriving/cmp/eq.rs @@ -4,7 +4,6 @@ use crate::deriving::generic::ty::*; use syntax::ast::{self, Expr, MetaItem, GenericArg}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::{sym, Symbol}; use syntax_pos::Span; diff --git a/src/libsyntax_ext/deriving/cmp/ord.rs b/src/libsyntax_ext/deriving/cmp/ord.rs index 8405d28984217..885cfee35658a 100644 --- a/src/libsyntax_ext/deriving/cmp/ord.rs +++ b/src/libsyntax_ext/deriving/cmp/ord.rs @@ -4,7 +4,6 @@ use crate::deriving::generic::ty::*; use syntax::ast::{self, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::sym; use syntax_pos::Span; diff --git a/src/libsyntax_ext/deriving/cmp/partial_eq.rs b/src/libsyntax_ext/deriving/cmp/partial_eq.rs index 4ab136538877a..337f7c5cfe238 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_eq.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_eq.rs @@ -4,7 +4,6 @@ use crate::deriving::generic::ty::*; use syntax::ast::{BinOpKind, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::sym; use syntax_pos::Span; diff --git a/src/libsyntax_ext/deriving/cmp/partial_ord.rs b/src/libsyntax_ext/deriving/cmp/partial_ord.rs index 18354e94815b5..0ec30f5924fbe 100644 --- a/src/libsyntax_ext/deriving/cmp/partial_ord.rs +++ b/src/libsyntax_ext/deriving/cmp/partial_ord.rs @@ -6,7 +6,6 @@ use crate::deriving::generic::ty::*; use syntax::ast::{self, BinOpKind, Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::{sym, Symbol}; use syntax_pos::Span; diff --git a/src/libsyntax_ext/deriving/debug.rs b/src/libsyntax_ext/deriving/debug.rs index 44ddbb98809b4..0f709630bf41e 100644 --- a/src/libsyntax_ext/deriving/debug.rs +++ b/src/libsyntax_ext/deriving/debug.rs @@ -7,7 +7,6 @@ use rustc_data_structures::thin_vec::ThinVec; use syntax::ast::{self, Ident}; use syntax::ast::{Expr, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::sym; use syntax_pos::{DUMMY_SP, Span}; diff --git a/src/libsyntax_ext/deriving/decodable.rs b/src/libsyntax_ext/deriving/decodable.rs index 8009f42b8cf95..27225006a9c72 100644 --- a/src/libsyntax_ext/deriving/decodable.rs +++ b/src/libsyntax_ext/deriving/decodable.rs @@ -7,7 +7,6 @@ use crate::deriving::generic::ty::*; use syntax::ast; use syntax::ast::{Expr, MetaItem, Mutability}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; diff --git a/src/libsyntax_ext/deriving/default.rs b/src/libsyntax_ext/deriving/default.rs index e147782db2c06..2fdea10b76f51 100644 --- a/src/libsyntax_ext/deriving/default.rs +++ b/src/libsyntax_ext/deriving/default.rs @@ -4,7 +4,6 @@ use crate::deriving::generic::ty::*; use syntax::ast::{Expr, MetaItem}; use syntax::ext::base::{Annotatable, DummyResult, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::{kw, sym}; use syntax::span_err; diff --git a/src/libsyntax_ext/deriving/encodable.rs b/src/libsyntax_ext/deriving/encodable.rs index cd89a42cf8270..ea26e1bdf9a10 100644 --- a/src/libsyntax_ext/deriving/encodable.rs +++ b/src/libsyntax_ext/deriving/encodable.rs @@ -88,7 +88,6 @@ use crate::deriving::generic::ty::*; use syntax::ast::{Expr, ExprKind, MetaItem, Mutability}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::Symbol; use syntax_pos::Span; diff --git a/src/libsyntax_ext/deriving/generic/mod.rs b/src/libsyntax_ext/deriving/generic/mod.rs index 1a4fce3754984..4a0c4a39f785b 100644 --- a/src/libsyntax_ext/deriving/generic/mod.rs +++ b/src/libsyntax_ext/deriving/generic/mod.rs @@ -187,7 +187,6 @@ use syntax::ast::{self, BinOpKind, EnumDef, Expr, Generics, Ident, PatKind}; use syntax::ast::{VariantData, GenericParamKind, GenericArg}; use syntax::attr; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::source_map::{self, respan}; use syntax::util::map_in_place::MapInPlace; use syntax::ptr::P; diff --git a/src/libsyntax_ext/deriving/generic/ty.rs b/src/libsyntax_ext/deriving/generic/ty.rs index 394beb141712d..399829eaefd14 100644 --- a/src/libsyntax_ext/deriving/generic/ty.rs +++ b/src/libsyntax_ext/deriving/generic/ty.rs @@ -6,7 +6,6 @@ pub use Ty::*; use syntax::ast::{self, Expr, GenericParamKind, Generics, Ident, SelfKind, GenericArg}; use syntax::ext::base::ExtCtxt; -use syntax::ext::build::AstBuilder; use syntax::source_map::{respan, DUMMY_SP}; use syntax::ptr::P; use syntax_pos::Span; diff --git a/src/libsyntax_ext/deriving/hash.rs b/src/libsyntax_ext/deriving/hash.rs index 7ad04aebf6e2e..9787722e81dd0 100644 --- a/src/libsyntax_ext/deriving/hash.rs +++ b/src/libsyntax_ext/deriving/hash.rs @@ -4,7 +4,6 @@ use crate::deriving::generic::ty::*; use syntax::ast::{Expr, MetaItem, Mutability}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::sym; use syntax_pos::Span; diff --git a/src/libsyntax_ext/deriving/mod.rs b/src/libsyntax_ext/deriving/mod.rs index cad79917af284..8cd2853e5383d 100644 --- a/src/libsyntax_ext/deriving/mod.rs +++ b/src/libsyntax_ext/deriving/mod.rs @@ -2,7 +2,6 @@ use syntax::ast::{self, MetaItem}; use syntax::ext::base::{Annotatable, ExtCtxt, MultiItemModifier}; -use syntax::ext::build::AstBuilder; use syntax::ptr::P; use syntax::symbol::{Symbol, sym}; use syntax_pos::Span; diff --git a/src/libsyntax_ext/env.rs b/src/libsyntax_ext/env.rs index 03c60e3f11f03..39fc90decc92a 100644 --- a/src/libsyntax_ext/env.rs +++ b/src/libsyntax_ext/env.rs @@ -5,7 +5,6 @@ use syntax::ast::{self, Ident, GenericArg}; use syntax::ext::base::{self, *}; -use syntax::ext::build::AstBuilder; use syntax::symbol::{kw, sym, Symbol}; use syntax_pos::Span; use syntax::tokenstream; diff --git a/src/libsyntax_ext/format.rs b/src/libsyntax_ext/format.rs index e53660b656865..f1e6cb027ca7a 100644 --- a/src/libsyntax_ext/format.rs +++ b/src/libsyntax_ext/format.rs @@ -8,7 +8,6 @@ use errors::Applicability; use syntax::ast; use syntax::ext::base::{self, *}; -use syntax::ext::build::AstBuilder; use syntax::parse::token; use syntax::ptr::P; use syntax::symbol::{Symbol, sym}; diff --git a/src/libsyntax_ext/global_allocator.rs b/src/libsyntax_ext/global_allocator.rs index 7225ceb8fc9b7..f788b51380433 100644 --- a/src/libsyntax_ext/global_allocator.rs +++ b/src/libsyntax_ext/global_allocator.rs @@ -3,7 +3,6 @@ use syntax::ast::{self, Arg, Attribute, Expr, FnHeader, Generics, Ident}; use syntax::attr::check_builtin_macro_attribute; use syntax::ext::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; use syntax::ext::base::{Annotatable, ExtCtxt}; -use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::SyntaxContext; use syntax::ptr::P; use syntax::symbol::{kw, sym, Symbol}; diff --git a/src/libsyntax_ext/proc_macro_harness.rs b/src/libsyntax_ext/proc_macro_harness.rs index 7c16d82fe3804..7913a7442edc7 100644 --- a/src/libsyntax_ext/proc_macro_harness.rs +++ b/src/libsyntax_ext/proc_macro_harness.rs @@ -4,7 +4,6 @@ use syntax::ast::{self, Ident}; use syntax::attr; use syntax::source_map::{ExpnInfo, ExpnKind, respan}; use syntax::ext::base::{ExtCtxt, MacroKind}; -use syntax::ext::build::AstBuilder; use syntax::ext::expand::ExpansionConfig; use syntax::ext::hygiene::ExpnId; use syntax::ext::proc_macro::is_proc_macro_attr; diff --git a/src/libsyntax_ext/source_util.rs b/src/libsyntax_ext/source_util.rs index 8ecfd4ddda7bf..2c8d53a231550 100644 --- a/src/libsyntax_ext/source_util.rs +++ b/src/libsyntax_ext/source_util.rs @@ -1,6 +1,5 @@ use syntax::{ast, panictry}; use syntax::ext::base::{self, *}; -use syntax::ext::build::AstBuilder; use syntax::parse::{self, token, DirectoryOwnership}; use syntax::print::pprust; use syntax::ptr::P; diff --git a/src/libsyntax_ext/test.rs b/src/libsyntax_ext/test.rs index ed4ea6b1bc90c..993ef25752757 100644 --- a/src/libsyntax_ext/test.rs +++ b/src/libsyntax_ext/test.rs @@ -4,7 +4,6 @@ use syntax::ast; use syntax::attr::{self, check_builtin_macro_attribute}; use syntax::ext::base::*; -use syntax::ext::build::AstBuilder; use syntax::ext::hygiene::SyntaxContext; use syntax::print::pprust; use syntax::source_map::respan; diff --git a/src/libsyntax_ext/test_harness.rs b/src/libsyntax_ext/test_harness.rs index 8cf043f7e767e..4b3903c7ad7d3 100644 --- a/src/libsyntax_ext/test_harness.rs +++ b/src/libsyntax_ext/test_harness.rs @@ -6,7 +6,6 @@ use syntax::ast::{self, Ident}; use syntax::attr; use syntax::entry::{self, EntryPointType}; use syntax::ext::base::{ExtCtxt, Resolver}; -use syntax::ext::build::AstBuilder; use syntax::ext::expand::ExpansionConfig; use syntax::ext::hygiene::{ExpnId, MacroKind}; use syntax::feature_gate::Features; diff --git a/src/test/ui-fulldeps/auxiliary/plugin-args.rs b/src/test/ui-fulldeps/auxiliary/plugin-args.rs index 36cee82893a06..f3cd2397b28fe 100644 --- a/src/test/ui-fulldeps/auxiliary/plugin-args.rs +++ b/src/test/ui-fulldeps/auxiliary/plugin-args.rs @@ -11,7 +11,6 @@ extern crate rustc_driver; use std::borrow::ToOwned; use syntax::ast; -use syntax::ext::build::AstBuilder; use syntax::ext::base::{SyntaxExtension, SyntaxExtensionKind}; use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager}; use syntax::print::pprust; diff --git a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs index 07302b6e68b31..77fa5c2cd7898 100644 --- a/src/test/ui-fulldeps/auxiliary/roman-numerals.rs +++ b/src/test/ui-fulldeps/auxiliary/roman-numerals.rs @@ -18,7 +18,6 @@ extern crate rustc_driver; use syntax::parse::token::{self, Token}; use syntax::tokenstream::TokenTree; use syntax::ext::base::{ExtCtxt, MacResult, DummyResult, MacEager}; -use syntax::ext::build::AstBuilder; // A trait for expr_usize. use syntax_pos::Span; use rustc_plugin::Registry; From d4227f6e0d4269fd69ade5702cdbb59a73d6319a Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Wed, 31 Jul 2019 08:01:36 -0400 Subject: [PATCH 08/22] Use Ident::new over setting span position via builder --- src/libsyntax/ext/build.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libsyntax/ext/build.rs b/src/libsyntax/ext/build.rs index 570ca012364f6..b4b15ba31b713 100644 --- a/src/libsyntax/ext/build.rs +++ b/src/libsyntax/ext/build.rs @@ -870,21 +870,21 @@ impl<'a> ExtCtxt<'a> { } pub fn meta_word(&self, sp: Span, w: ast::Name) -> ast::MetaItem { - attr::mk_word_item(Ident::with_empty_ctxt(w).with_span_pos(sp)) + attr::mk_word_item(Ident::new(w, sp)) } pub fn meta_list_item_word(&self, sp: Span, w: ast::Name) -> ast::NestedMetaItem { - attr::mk_nested_word_item(Ident::with_empty_ctxt(w).with_span_pos(sp)) + attr::mk_nested_word_item(Ident::new(w, sp)) } pub fn meta_list(&self, sp: Span, name: ast::Name, mis: Vec) -> ast::MetaItem { - attr::mk_list_item(sp, Ident::with_empty_ctxt(name).with_span_pos(sp), mis) + attr::mk_list_item(sp, Ident::new(name, sp), mis) } pub fn meta_name_value(&self, span: Span, name: ast::Name, lit_kind: ast::LitKind) -> ast::MetaItem { - attr::mk_name_value_item(span, Ident::with_empty_ctxt(name).with_span_pos(span), + attr::mk_name_value_item(span, Ident::new(name, span), lit_kind, span) } From c146344e32018a8b28c456352a873f9feafd6ff3 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 30 Jul 2019 13:40:43 -0400 Subject: [PATCH 09/22] Decode AttrId via mk_attr_id --- src/librustc_metadata/decoder.rs | 9 +-------- src/libsyntax/ast.rs | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 11 deletions(-) diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 8e76dbb882e3b..9668e68e90a3e 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -980,14 +980,7 @@ impl<'a, 'tcx> CrateMetadata { } fn get_attributes(&self, item: &Entry<'tcx>, sess: &Session) -> Vec { - item.attributes - .decode((self, sess)) - .map(|mut attr| { - // Need new unique IDs: old thread-local IDs won't map to new threads. - attr.id = attr::mk_attr_id(); - attr - }) - .collect() + item.attributes.decode((self, sess)).collect() } // Translate a DefId from the current compilation environment to a DefId diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b633705a65f5d..2938487393dc7 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -2104,9 +2104,7 @@ pub enum AttrStyle { Inner, } -#[derive( - Clone, PartialEq, Eq, RustcEncodable, RustcDecodable, Hash, Debug, PartialOrd, Ord, Copy, -)] +#[derive(Clone, PartialEq, Eq, Hash, Debug, PartialOrd, Ord, Copy)] pub struct AttrId(pub usize); impl Idx for AttrId { @@ -2118,6 +2116,18 @@ impl Idx for AttrId { } } +impl rustc_serialize::Encodable for AttrId { + fn encode(&self, s: &mut S) -> Result<(), S::Error> { + s.emit_unit() + } +} + +impl rustc_serialize::Decodable for AttrId { + fn decode(d: &mut D) -> Result { + d.read_nil().map(|_| crate::attr::mk_attr_id()) + } +} + /// Metadata associated with an item. /// Doc-comments are promoted to attributes that have `is_sugared_doc = true`. #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] From c34466c3dfa01cbadae9158d614a59007a2f0b55 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 24 Jul 2019 16:08:01 +0200 Subject: [PATCH 10/22] cast: no need to catch errors any more, force_bits should succeed --- src/librustc_mir/interpret/cast.rs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 980697360eb75..0f8f649cfed73 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -250,12 +250,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { RawPtr(_) => Ok(ptr.into()), Int(_) | Uint(_) => { let size = self.memory.pointer_size(); - - match self.force_bits(Scalar::Ptr(ptr), size) { - Ok(bits) => self.cast_from_int(bits, src_layout, dest_layout), - Err(_) if dest_layout.size == size => Ok(ptr.into()), - Err(e) => Err(e), - } + let bits = self.force_bits(Scalar::Ptr(ptr), size)?; + self.cast_from_int(bits, src_layout, dest_layout) } _ => bug!("invalid MIR: ptr to {:?} cast", dest_layout.ty) } From 4a55c461c16fc3fff1520f4404ab081bbc0fa2ec Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 24 Jul 2019 16:08:50 +0200 Subject: [PATCH 11/22] operator: implement binary_op strictly by first checking the type, then dispatching further; call ptr_op machine hook only for pointer types --- src/librustc_mir/const_eval.rs | 2 +- src/librustc_mir/interpret/machine.rs | 5 ++-- src/librustc_mir/interpret/operator.rs | 39 +++++++++++++------------- 3 files changed, 22 insertions(+), 24 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 37d4c5b2f09ce..2eec10a2a4f38 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -397,7 +397,7 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ) } - fn ptr_op( + fn binary_ptr_op( _ecx: &InterpCx<'mir, 'tcx, Self>, _bin_op: mir::BinOp, _left: ImmTy<'tcx>, diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index e3f16a3c9ea45..db1b1a751b463 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -165,11 +165,10 @@ pub trait Machine<'mir, 'tcx>: Sized { def_id: DefId, ) -> InterpResult<'tcx, Cow<'tcx, Allocation>>; - /// Called for all binary operations on integer(-like) types when one operand is a pointer - /// value, and for the `Offset` operation that is inherently about pointers. + /// Called for all binary operations where the LHS has pointer type. /// /// Returns a (value, overflowed) pair if the operation succeeded - fn ptr_op( + fn binary_ptr_op( ecx: &InterpCx<'mir, 'tcx, Self>, bin_op: mir::BinOp, left: ImmTy<'tcx, Self::PointerTag>, diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index b4edee72a4d19..d56674f8bdbc3 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -290,30 +290,29 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { FloatTy::F64 => self.binary_float_op(bin_op, left.to_f64()?, right.to_f64()?), }) } - _ => { - // Must be integer(-like) types. Don't forget about == on fn pointers. - assert!( - left.layout.ty.is_integral() || - left.layout.ty.is_unsafe_ptr() || left.layout.ty.is_fn_ptr(), - "Unexpected LHS type {:?} for BinOp {:?}", left.layout.ty, bin_op); + _ if left.layout.ty.is_integral() => { + // the RHS type can be different, e.g. for shifts -- but it has to be integral, too assert!( - right.layout.ty.is_integral() || - right.layout.ty.is_unsafe_ptr() || right.layout.ty.is_fn_ptr(), - "Unexpected RHS type {:?} for BinOp {:?}", right.layout.ty, bin_op); - - // Handle operations that support pointer values - if left.to_scalar_ptr()?.is_ptr() || - right.to_scalar_ptr()?.is_ptr() || - bin_op == mir::BinOp::Offset - { - return M::ptr_op(self, bin_op, left, right); - } + right.layout.ty.is_integral(), + "Unexpected types for BinOp: {:?} {:?} {:?}", + left.layout.ty, bin_op, right.layout.ty + ); - // Everything else only works with "proper" bits - let l = left.to_bits().expect("we checked is_ptr"); - let r = right.to_bits().expect("we checked is_ptr"); + let l = self.force_bits(left.to_scalar()?, left.layout.size)?; + let r = self.force_bits(right.to_scalar()?, right.layout.size)?; self.binary_int_op(bin_op, l, left.layout, r, right.layout) } + _ if left.layout.ty.is_unsafe_ptr() || left.layout.ty.is_fn_ptr() => { + // The RHS type must be the same *or an integer type* (for `Offset`) + assert!( + right.layout.ty == left.layout.ty || right.layout.ty.is_integral(), + "Unexpected types for BinOp: {:?} {:?} {:?}", + left.layout.ty, bin_op, right.layout.ty + ); + + M::binary_ptr_op(self, bin_op, left, right) + } + _ => bug!("Invalid MIR: bad LHS type for binop: {:?}", left.layout.ty), } } From ecc0f4c1a05697d08dedc5535395c51fa568b0b9 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 24 Jul 2019 19:01:12 +0200 Subject: [PATCH 12/22] turn cast_immediate into its own function --- src/librustc_mir/interpret/cast.rs | 75 ++++++++++++++------------- src/librustc_mir/interpret/operand.rs | 14 +++++ 2 files changed, 54 insertions(+), 35 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 0f8f649cfed73..928cc0f08fd45 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -11,7 +11,7 @@ use rustc::mir::interpret::{ }; use rustc::mir::CastKind; -use super::{InterpCx, Machine, PlaceTy, OpTy, Immediate, FnVal}; +use super::{InterpCx, Machine, PlaceTy, OpTy, ImmTy, Immediate, FnVal}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool { @@ -37,40 +37,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Misc | Pointer(PointerCast::MutToConstPointer) => { let src = self.read_immediate(src)?; - - if self.type_is_fat_ptr(src.layout.ty) { - match (*src, self.type_is_fat_ptr(dest.layout.ty)) { - // pointers to extern types - (Immediate::Scalar(_),_) | - // slices and trait objects to other slices/trait objects - (Immediate::ScalarPair(..), true) => { - // No change to immediate - self.write_immediate(*src, dest)?; - } - // slices and trait objects to thin pointers (dropping the metadata) - (Immediate::ScalarPair(data, _), false) => { - self.write_scalar(data, dest)?; - } - } - } else { - match src.layout.variants { - layout::Variants::Single { index } => { - if let Some(discr) = - src.layout.ty.discriminant_for_variant(*self.tcx, index) - { - // Cast from a univariant enum - assert!(src.layout.is_zst()); - return self.write_scalar( - Scalar::from_uint(discr.val, dest.layout.size), - dest); - } - } - layout::Variants::Multiple { .. } => {}, - } - - let dest_val = self.cast_scalar(src.to_scalar()?, src.layout, dest.layout)?; - self.write_scalar(dest_val, dest)?; - } + let res = self.cast_immediate(src, dest.layout)?; + self.write_immediate(res, dest)?; } Pointer(PointerCast::ReifyFnPointer) => { @@ -126,6 +94,43 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Ok(()) } + fn cast_immediate( + &self, + src: ImmTy<'tcx, M::PointerTag>, + dest_layout: TyLayout<'tcx>, + ) -> InterpResult<'tcx, Immediate> { + if self.type_is_fat_ptr(src.layout.ty) { + return match (*src, self.type_is_fat_ptr(dest_layout.ty)) { + // pointers to extern types + (Immediate::Scalar(_),_) | + // slices and trait objects to other slices/trait objects + (Immediate::ScalarPair(..), true) => { + // No change to immediate + Ok(*src) + } + // slices and trait objects to thin pointers (dropping the metadata) + (Immediate::ScalarPair(data, _), false) => { + Ok(data.into()) + } + }; + } else { + match src.layout.variants { + layout::Variants::Single { index } => { + if let Some(discr) = + src.layout.ty.discriminant_for_variant(*self.tcx, index) + { + // Cast from a univariant enum + assert!(src.layout.is_zst()); + return Ok(Scalar::from_uint(discr.val, dest_layout.size).into()); + } + } + layout::Variants::Multiple { .. } => {}, + } + + return Ok(self.cast_scalar(src.to_scalar()?, src.layout, dest_layout)?.into()); + } + } + fn cast_scalar( &self, val: Scalar, diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index 1816171d7b127..c556fa74f128a 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -33,6 +33,20 @@ pub enum Immediate { ScalarPair(ScalarMaybeUndef, ScalarMaybeUndef), } +impl From> for Immediate { + #[inline(always)] + fn from(val: ScalarMaybeUndef) -> Self { + Immediate::Scalar(val) + } +} + +impl From> for Immediate { + #[inline(always)] + fn from(val: Scalar) -> Self { + Immediate::Scalar(val.into()) + } +} + impl<'tcx, Tag> Immediate { #[inline] pub fn from_scalar(val: Scalar) -> Self { From 479200b9a9643ad2c4516f94e0a1fd780a879333 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 24 Jul 2019 20:05:53 +0200 Subject: [PATCH 13/22] refactor cast_immediate to dispatch on the type first, and on the value second --- src/librustc_mir/interpret/cast.rs | 110 ++++++++++++----------------- 1 file changed, 46 insertions(+), 64 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 928cc0f08fd45..29b4cbb71e7f2 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -14,15 +14,6 @@ use rustc::mir::CastKind; use super::{InterpCx, Machine, PlaceTy, OpTy, ImmTy, Immediate, FnVal}; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { - fn type_is_fat_ptr(&self, ty: Ty<'tcx>) -> bool { - match ty.sty { - ty::RawPtr(ty::TypeAndMut { ty, .. }) | - ty::Ref(_, ty, _) => !self.type_is_sized(ty), - ty::Adt(def, _) if def.is_box() => !self.type_is_sized(ty.boxed_ty()), - _ => false, - } - } - pub fn cast( &mut self, src: OpTy<'tcx, M::PointerTag>, @@ -99,68 +90,59 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { src: ImmTy<'tcx, M::PointerTag>, dest_layout: TyLayout<'tcx>, ) -> InterpResult<'tcx, Immediate> { - if self.type_is_fat_ptr(src.layout.ty) { - return match (*src, self.type_is_fat_ptr(dest_layout.ty)) { - // pointers to extern types - (Immediate::Scalar(_),_) | - // slices and trait objects to other slices/trait objects - (Immediate::ScalarPair(..), true) => { - // No change to immediate - Ok(*src) - } - // slices and trait objects to thin pointers (dropping the metadata) - (Immediate::ScalarPair(data, _), false) => { - Ok(data.into()) - } - }; - } else { - match src.layout.variants { - layout::Variants::Single { index } => { - if let Some(discr) = - src.layout.ty.discriminant_for_variant(*self.tcx, index) - { - // Cast from a univariant enum - assert!(src.layout.is_zst()); - return Ok(Scalar::from_uint(discr.val, dest_layout.size).into()); - } - } - layout::Variants::Multiple { .. } => {}, - } - - return Ok(self.cast_scalar(src.to_scalar()?, src.layout, dest_layout)?.into()); - } - } - - fn cast_scalar( - &self, - val: Scalar, - src_layout: TyLayout<'tcx>, - dest_layout: TyLayout<'tcx>, - ) -> InterpResult<'tcx, Scalar> { use rustc::ty::TyKind::*; - trace!("Casting {:?}: {:?} to {:?}", val, src_layout.ty, dest_layout.ty); + trace!("Casting {:?}: {:?} to {:?}", *src, src.layout.ty, dest_layout.ty); - match src_layout.ty.sty { + match src.layout.ty.sty { // Floating point - Float(FloatTy::F32) => self.cast_from_float(val.to_f32()?, dest_layout.ty), - Float(FloatTy::F64) => self.cast_from_float(val.to_f64()?, dest_layout.ty), - // Integer(-like), including fn ptr casts and casts from enums that - // are represented as integers (this excludes univariant enums, which - // are handled in `cast` directly). - _ => { + Float(FloatTy::F32) => + return Ok(self.cast_from_float(src.to_scalar()?.to_f32()?, dest_layout.ty)?.into()), + Float(FloatTy::F64) => + return Ok(self.cast_from_float(src.to_scalar()?.to_f64()?, dest_layout.ty)?.into()), + // The rest is integer/pointer-"like", including fn ptr casts and casts from enums that + // are represented as integers. + _ => assert!( - src_layout.ty.is_bool() || src_layout.ty.is_char() || - src_layout.ty.is_enum() || src_layout.ty.is_integral() || - src_layout.ty.is_unsafe_ptr() || src_layout.ty.is_fn_ptr() || - src_layout.ty.is_region_ptr(), - "Unexpected cast from type {:?}", src_layout.ty - ); - match val.to_bits_or_ptr(src_layout.size, self) { - Err(ptr) => self.cast_from_ptr(ptr, src_layout, dest_layout), - Ok(data) => self.cast_from_int(data, src_layout, dest_layout), + src.layout.ty.is_bool() || src.layout.ty.is_char() || + src.layout.ty.is_enum() || src.layout.ty.is_integral() || + src.layout.ty.is_unsafe_ptr() || src.layout.ty.is_fn_ptr() || + src.layout.ty.is_region_ptr(), + "Unexpected cast from type {:?}", src.layout.ty + ) + } + + // Handle cast the metadata away from a fat pointer. + if dest_layout.size != src.layout.size { + assert_eq!(dest_layout.size, self.memory.pointer_size()); + return match *src { + Immediate::ScalarPair(data, _) => Ok(data.into()), + Immediate::Scalar(..) => + bug!( + "{:?} input to a fat-to-thin cast ({:?} -> {:?})", + *src, src.layout.ty, dest_layout.ty + ), + }; + } + + // Handle cast from a univariant (ZST) enum + match src.layout.variants { + layout::Variants::Single { index } => { + if let Some(discr) = + src.layout.ty.discriminant_for_variant(*self.tcx, index) + { + assert!(src.layout.is_zst()); + return Ok(Scalar::from_uint(discr.val, dest_layout.size).into()); } } + layout::Variants::Multiple { .. } => {}, } + + // Handle all the rest. + let val = src.to_scalar()?; + Ok(match val.to_bits_or_ptr(src.layout.size, self) { + Err(ptr) => self.cast_from_ptr(ptr, src.layout, dest_layout)?, + Ok(data) => self.cast_from_int(data, src.layout, dest_layout)?, + }.into()) } fn cast_from_int( From c79f2228176118d278923e73d722e0a0de5185c8 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 24 Jul 2019 20:20:55 +0200 Subject: [PATCH 14/22] use From to convert scalars to immediates --- src/librustc_mir/interpret/operand.rs | 21 ++++++++------------- src/librustc_mir/interpret/terminator.rs | 4 ++-- 2 files changed, 10 insertions(+), 15 deletions(-) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index c556fa74f128a..b5289187ef08f 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -48,11 +48,6 @@ impl From> for Immediate { } impl<'tcx, Tag> Immediate { - #[inline] - pub fn from_scalar(val: Scalar) -> Self { - Immediate::Scalar(ScalarMaybeUndef::Scalar(val)) - } - pub fn new_slice( val: Scalar, len: u64, @@ -197,7 +192,7 @@ impl<'tcx, Tag: Copy> ImmTy<'tcx, Tag> { #[inline] pub fn from_scalar(val: Scalar, layout: TyLayout<'tcx>) -> Self { - ImmTy { imm: Immediate::from_scalar(val), layout } + ImmTy { imm: val.into(), layout } } #[inline] @@ -255,7 +250,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let ptr = match self.check_mplace_access(mplace, None)? { Some(ptr) => ptr, None => return Ok(Some(ImmTy { // zero-sized type - imm: Immediate::Scalar(Scalar::zst().into()), + imm: Scalar::zst().into(), layout: mplace.layout, })), }; @@ -266,7 +261,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { .get(ptr.alloc_id)? .read_scalar(self, ptr, mplace.layout.size)?; Ok(Some(ImmTy { - imm: Immediate::Scalar(scalar), + imm: scalar.into(), layout: mplace.layout, })) } @@ -368,7 +363,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let field = field.try_into().unwrap(); let field_layout = op.layout.field(self, field)?; if field_layout.is_zst() { - let immediate = Immediate::Scalar(Scalar::zst().into()); + let immediate = Scalar::zst().into(); return Ok(OpTy { op: Operand::Immediate(immediate), layout: field_layout }); } let offset = op.layout.fields.offset(field); @@ -378,7 +373,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // extract fields from types with `ScalarPair` ABI Immediate::ScalarPair(a, b) => { let val = if offset.bytes() == 0 { a } else { b }; - Immediate::Scalar(val) + Immediate::from(val) }, Immediate::Scalar(val) => bug!("field access on non aggregate {:#?}, {:#?}", val, op.layout), @@ -415,7 +410,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Deref => self.deref_operand(base)?.into(), Subslice { .. } | ConstantIndex { .. } | Index(_) => if base.layout.is_zst() { OpTy { - op: Operand::Immediate(Immediate::Scalar(Scalar::zst().into())), + op: Operand::Immediate(Scalar::zst().into()), // the actual index doesn't matter, so we just pick a convenient one like 0 layout: base.layout.field(self, 0)?, } @@ -439,7 +434,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let layout = self.layout_of_local(frame, local, layout)?; let op = if layout.is_zst() { // Do not read from ZST, they might not be initialized - Operand::Immediate(Immediate::Scalar(Scalar::zst().into())) + Operand::Immediate(Scalar::zst().into()) } else { frame.locals[local].access()? }; @@ -567,7 +562,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { Operand::Indirect(MemPlace::from_ptr(ptr, align)) }, ConstValue::Scalar(x) => - Operand::Immediate(Immediate::Scalar(tag_scalar(x).into())), + Operand::Immediate(tag_scalar(x).into()), ConstValue::Slice { data, start, end } => { // We rely on mutability being set correctly in `data` to prevent writes // where none should happen. diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 27bd0f8889634..8258192db4fdb 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -8,7 +8,7 @@ use rustc_target::spec::abi::Abi; use super::{ InterpResult, PointerArithmetic, InterpError, Scalar, - InterpCx, Machine, Immediate, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, + InterpCx, Machine, OpTy, ImmTy, PlaceTy, MPlaceTy, StackPopCleanup, FnVal, }; impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { @@ -462,7 +462,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { // Adjust receiver argument. args[0] = OpTy::from(ImmTy { layout: this_receiver_ptr, - imm: Immediate::Scalar(receiver_place.ptr.into()) + imm: receiver_place.ptr.into() }); trace!("Patched self operand to {:#?}", args[0]); // recurse with concrete function From f5f0ce9622c708e4c2cd9de79048001d7b8f1523 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Wed, 24 Jul 2019 20:09:18 +0200 Subject: [PATCH 15/22] fix casts from fat pointers --- src/librustc_mir/interpret/cast.rs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 29b4cbb71e7f2..04ef7b5f7e5ac 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -111,9 +111,13 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) } - // Handle cast the metadata away from a fat pointer. - if dest_layout.size != src.layout.size { + // Handle casting the metadata away from a fat pointer. + if src.layout.ty.is_unsafe_ptr() && dest_layout.ty.is_unsafe_ptr() && + dest_layout.size != src.layout.size + { + assert_eq!(src.layout.size, 2*self.memory.pointer_size()); assert_eq!(dest_layout.size, self.memory.pointer_size()); + assert!(dest_layout.ty.is_unsafe_ptr()); return match *src { Immediate::ScalarPair(data, _) => Ok(data.into()), Immediate::Scalar(..) => @@ -124,6 +128,15 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; } + // Handle casting reference to raw ptr or raw to other raw (might be a fat ptr). + if (src.layout.ty.is_region_ptr() || src.layout.ty.is_unsafe_ptr()) && + dest_layout.ty.is_unsafe_ptr() + { + // The only possible size-unequal case was handled above. + assert_eq!(src.layout.size, dest_layout.size); + return Ok(*src); + } + // Handle cast from a univariant (ZST) enum match src.layout.variants { layout::Variants::Single { index } => { From 9cfda48906c14fe12f5e51820427be5bb95283b4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Jul 2019 00:06:47 +0200 Subject: [PATCH 16/22] improve error when CTFE does ptr-int-cast; update tests --- src/librustc_mir/const_eval.rs | 13 +++++++++++-- src/librustc_mir/interpret/machine.rs | 6 +----- src/test/ui/consts/const-eval/const_raw_ptr_ops.rs | 4 ++-- .../ui/consts/const-eval/const_raw_ptr_ops.stderr | 14 +++++++++++--- src/test/ui/consts/const-eval/issue-52442.rs | 2 +- src/test/ui/consts/const-eval/issue-52442.stderr | 8 +++----- .../ui/consts/const-eval/match-test-ptr-null.rs | 5 ++--- .../consts/const-eval/match-test-ptr-null.stderr | 12 ++++++------ 8 files changed, 37 insertions(+), 27 deletions(-) diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 2eec10a2a4f38..b54fe5e09bef6 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -20,10 +20,10 @@ use rustc_data_structures::fx::FxHashMap; use syntax::source_map::{Span, DUMMY_SP}; use crate::interpret::{self, - PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar, + PlaceTy, MPlaceTy, OpTy, ImmTy, Immediate, Scalar, Pointer, RawConst, ConstValue, InterpResult, InterpErrorInfo, InterpError, GlobalId, InterpCx, StackPopCleanup, - Allocation, AllocId, MemoryKind, + Allocation, AllocId, MemoryKind, Memory, snapshot, RefTracking, intern_const_alloc_recursive, }; @@ -397,6 +397,15 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir, ) } + fn ptr_to_int( + _mem: &Memory<'mir, 'tcx, Self>, + _ptr: Pointer, + ) -> InterpResult<'tcx, u64> { + Err( + ConstEvalError::NeedsRfc("pointer-to-integer cast".to_string()).into(), + ) + } + fn binary_ptr_op( _ecx: &InterpCx<'mir, 'tcx, Self>, _bin_op: mir::BinOp, diff --git a/src/librustc_mir/interpret/machine.rs b/src/librustc_mir/interpret/machine.rs index db1b1a751b463..be8ad49bb3385 100644 --- a/src/librustc_mir/interpret/machine.rs +++ b/src/librustc_mir/interpret/machine.rs @@ -233,7 +233,6 @@ pub trait Machine<'mir, 'tcx>: Sized { extra: Self::FrameExtra, ) -> InterpResult<'tcx>; - #[inline(always)] fn int_to_ptr( _mem: &Memory<'mir, 'tcx, Self>, int: u64, @@ -245,11 +244,8 @@ pub trait Machine<'mir, 'tcx>: Sized { }).into()) } - #[inline(always)] fn ptr_to_int( _mem: &Memory<'mir, 'tcx, Self>, _ptr: Pointer, - ) -> InterpResult<'tcx, u64> { - err!(ReadPointerAsBytes) - } + ) -> InterpResult<'tcx, u64>; } diff --git a/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs b/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs index 44266682a5c6c..9be1374f85d99 100644 --- a/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs +++ b/src/test/ui/consts/const-eval/const_raw_ptr_ops.rs @@ -4,8 +4,8 @@ fn main() {} // unconst and bad, will thus error in miri const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; //~ ERROR any use of this -// unconst and fine -const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; +// unconst and bad, will thus error in miri +const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; //~ ERROR any use of this // unconst and fine const Y: usize = unsafe { 42usize as *const i32 as usize + 1 }; // unconst and bad, will thus error in miri diff --git a/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr b/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr index a12575b3975b6..2cba833a74896 100644 --- a/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr +++ b/src/test/ui/consts/const-eval/const_raw_ptr_ops.stderr @@ -8,13 +8,21 @@ LL | const X: bool = unsafe { &1 as *const i32 == &2 as *const i32 }; | = note: `#[deny(const_err)]` on by default +error: any use of this value will cause an error + --> $DIR/const_raw_ptr_ops.rs:8:27 + | +LL | const X2: bool = unsafe { 42 as *const i32 == 43 as *const i32 }; + | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants + error: any use of this value will cause an error --> $DIR/const_raw_ptr_ops.rs:12:28 | LL | const Y2: usize = unsafe { &1 as *const i32 as usize + 1 }; - | ---------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | ---------------------------^^^^^^^^^^^^^^^^^^^^^^^^^------- | | - | "pointer arithmetic or comparison" needs an rfc before being allowed inside constants + | "pointer-to-integer cast" needs an rfc before being allowed inside constants error: any use of this value will cause an error --> $DIR/const_raw_ptr_ops.rs:16:26 @@ -32,5 +40,5 @@ LL | const Z3: i32 = unsafe { *(44 as *const i32) }; | | | a memory access tried to interpret some bytes as a pointer -error: aborting due to 4 previous errors +error: aborting due to 5 previous errors diff --git a/src/test/ui/consts/const-eval/issue-52442.rs b/src/test/ui/consts/const-eval/issue-52442.rs index 2989b200b2fc4..ea24578c7dd0c 100644 --- a/src/test/ui/consts/const-eval/issue-52442.rs +++ b/src/test/ui/consts/const-eval/issue-52442.rs @@ -1,5 +1,5 @@ fn main() { [(); { &loop { break } as *const _ as usize } ]; //~^ ERROR casting pointers to integers in constants is unstable - //~| ERROR it is undefined behavior to use this value + //~| ERROR evaluation of constant value failed } diff --git a/src/test/ui/consts/const-eval/issue-52442.stderr b/src/test/ui/consts/const-eval/issue-52442.stderr index 88c94d917fe0e..5bd4979bdb33c 100644 --- a/src/test/ui/consts/const-eval/issue-52442.stderr +++ b/src/test/ui/consts/const-eval/issue-52442.stderr @@ -7,13 +7,11 @@ LL | [(); { &loop { break } as *const _ as usize } ]; = note: for more information, see https://github.com/rust-lang/rust/issues/51910 = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable -error[E0080]: it is undefined behavior to use this value - --> $DIR/issue-52442.rs:2:11 +error[E0080]: evaluation of constant value failed + --> $DIR/issue-52442.rs:2:13 | LL | [(); { &loop { break } as *const _ as usize } ]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants error: aborting due to 2 previous errors diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.rs b/src/test/ui/consts/const-eval/match-test-ptr-null.rs index 50757afaf5651..9c930221e73e3 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.rs +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.rs @@ -1,3 +1,4 @@ + fn main() { // Make sure match uses the usual pointer comparison code path -- i.e., it should complain // that pointer comparison is disallowed, not that parts of a pointer are accessed as raw @@ -5,11 +6,9 @@ fn main() { let _: [u8; 0] = [4; { match &1 as *const i32 as usize { //~^ ERROR casting pointers to integers in constants - //~| NOTE for more information, see //~| ERROR constant contains unimplemented expression type - 0 => 42, //~ ERROR constant contains unimplemented expression type - //~^ NOTE "pointer arithmetic or comparison" needs an rfc before being allowed //~| ERROR evaluation of constant value failed + 0 => 42, //~ ERROR constant contains unimplemented expression type n => n, } }]; diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr index d8a3bac5ce689..9bb561f31ebb0 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr @@ -1,5 +1,5 @@ error[E0658]: casting pointers to integers in constants is unstable - --> $DIR/match-test-ptr-null.rs:6:15 + --> $DIR/match-test-ptr-null.rs:7:15 | LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,22 +8,22 @@ LL | match &1 as *const i32 as usize { = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable error[E0019]: constant contains unimplemented expression type - --> $DIR/match-test-ptr-null.rs:6:15 + --> $DIR/match-test-ptr-null.rs:7:15 | LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0019]: constant contains unimplemented expression type - --> $DIR/match-test-ptr-null.rs:10:13 + --> $DIR/match-test-ptr-null.rs:11:13 | LL | 0 => 42, | ^ error[E0080]: evaluation of constant value failed - --> $DIR/match-test-ptr-null.rs:10:13 + --> $DIR/match-test-ptr-null.rs:7:15 | -LL | 0 => 42, - | ^ "pointer arithmetic or comparison" needs an rfc before being allowed inside constants +LL | match &1 as *const i32 as usize { + | ^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants error: aborting due to 4 previous errors From b0b2a2f98bc13a522db95fc946b75204a2ff463d Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Jul 2019 00:22:05 +0200 Subject: [PATCH 17/22] get rid of some remaining type-based dispatching in cast code --- src/librustc_mir/interpret/cast.rs | 70 +++++++++++------------------- 1 file changed, 25 insertions(+), 45 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 04ef7b5f7e5ac..1309006026e21 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -7,7 +7,7 @@ use syntax::symbol::sym; use rustc_apfloat::ieee::{Single, Double}; use rustc_apfloat::{Float, FloatConvert}; use rustc::mir::interpret::{ - Scalar, InterpResult, Pointer, PointerArithmetic, InterpError, + Scalar, InterpResult, PointerArithmetic, InterpError, }; use rustc::mir::CastKind; @@ -111,6 +111,19 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) } + // Handle cast from a univariant (ZST) enum + match src.layout.variants { + layout::Variants::Single { index } => { + if let Some(discr) = + src.layout.ty.discriminant_for_variant(*self.tcx, index) + { + assert!(src.layout.is_zst()); + return Ok(Scalar::from_uint(discr.val, dest_layout.size).into()); + } + } + layout::Variants::Multiple { .. } => {}, + } + // Handle casting the metadata away from a fat pointer. if src.layout.ty.is_unsafe_ptr() && dest_layout.ty.is_unsafe_ptr() && dest_layout.size != src.layout.size @@ -118,8 +131,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert_eq!(src.layout.size, 2*self.memory.pointer_size()); assert_eq!(dest_layout.size, self.memory.pointer_size()); assert!(dest_layout.ty.is_unsafe_ptr()); - return match *src { - Immediate::ScalarPair(data, _) => Ok(data.into()), + match *src { + Immediate::ScalarPair(data, _) => + return Ok(data.into()), Immediate::Scalar(..) => bug!( "{:?} input to a fat-to-thin cast ({:?} -> {:?})", @@ -128,8 +142,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { }; } - // Handle casting reference to raw ptr or raw to other raw (might be a fat ptr). - if (src.layout.ty.is_region_ptr() || src.layout.ty.is_unsafe_ptr()) && + // Handle casting any ptr to raw ptr (might be a fat ptr). + if (src.layout.ty.is_region_ptr() || src.layout.ty.is_unsafe_ptr() || src.layout.ty.is_fn_ptr()) && dest_layout.ty.is_unsafe_ptr() { // The only possible size-unequal case was handled above. @@ -137,25 +151,12 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { return Ok(*src); } - // Handle cast from a univariant (ZST) enum - match src.layout.variants { - layout::Variants::Single { index } => { - if let Some(discr) = - src.layout.ty.discriminant_for_variant(*self.tcx, index) - { - assert!(src.layout.is_zst()); - return Ok(Scalar::from_uint(discr.val, dest_layout.size).into()); - } - } - layout::Variants::Multiple { .. } => {}, - } - - // Handle all the rest. - let val = src.to_scalar()?; - Ok(match val.to_bits_or_ptr(src.layout.size, self) { - Err(ptr) => self.cast_from_ptr(ptr, src.layout, dest_layout)?, - Ok(data) => self.cast_from_int(data, src.layout, dest_layout)?, - }.into()) + // For all remaining casts, we either + // (a) cast a raw ptr to usize, or + // (b) cast from an integer-like (including bool, char, enums). + // In both cases we want the bits. + let bits = self.force_bits(src.to_scalar()?, src.layout.size)?; + Ok(self.cast_from_int(bits, src.layout, dest_layout)?.into()) } fn cast_from_int( @@ -236,27 +237,6 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } } - fn cast_from_ptr( - &self, - ptr: Pointer, - src_layout: TyLayout<'tcx>, - dest_layout: TyLayout<'tcx>, - ) -> InterpResult<'tcx, Scalar> { - use rustc::ty::TyKind::*; - - match dest_layout.ty.sty { - // Casting to a reference or fn pointer is not permitted by rustc, - // no need to support it here. - RawPtr(_) => Ok(ptr.into()), - Int(_) | Uint(_) => { - let size = self.memory.pointer_size(); - let bits = self.force_bits(Scalar::Ptr(ptr), size)?; - self.cast_from_int(bits, src_layout, dest_layout) - } - _ => bug!("invalid MIR: ptr to {:?} cast", dest_layout.ty) - } - } - fn unsize_into_ptr( &mut self, src: OpTy<'tcx, M::PointerTag>, From 3bf7377bcc84142c4301f1cdee2f4c77f1fc8a93 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Jul 2019 01:02:41 +0200 Subject: [PATCH 18/22] add is_any_ptr type test; this also helps pacify tidy --- src/librustc/ty/sty.rs | 6 ++++++ src/librustc_mir/interpret/cast.rs | 6 ++---- src/librustc_mir/interpret/operator.rs | 2 +- src/test/ui/consts/const-eval/match-test-ptr-null.rs | 1 - 4 files changed, 9 insertions(+), 6 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 77b8ebba21669..14da3875cdd79 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1863,6 +1863,12 @@ impl<'tcx> TyS<'tcx> { } } + /// Tests if this is any kind of primitive pointer type (reference, raw pointer, fn pointer). + #[inline] + pub fn is_any_ptr(&self) -> bool { + self.is_region_ptr() || self.is_unsafe_ptr() || self.is_fn_ptr() + } + /// Returns `true` if this type is an `Arc`. #[inline] pub fn is_arc(&self) -> bool { diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 1309006026e21..16fb083b7fc2f 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -105,8 +105,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { assert!( src.layout.ty.is_bool() || src.layout.ty.is_char() || src.layout.ty.is_enum() || src.layout.ty.is_integral() || - src.layout.ty.is_unsafe_ptr() || src.layout.ty.is_fn_ptr() || - src.layout.ty.is_region_ptr(), + src.layout.ty.is_any_ptr(), "Unexpected cast from type {:?}", src.layout.ty ) } @@ -143,8 +142,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { } // Handle casting any ptr to raw ptr (might be a fat ptr). - if (src.layout.ty.is_region_ptr() || src.layout.ty.is_unsafe_ptr() || src.layout.ty.is_fn_ptr()) && - dest_layout.ty.is_unsafe_ptr() + if src.layout.ty.is_any_ptr() && dest_layout.ty.is_unsafe_ptr() { // The only possible size-unequal case was handled above. assert_eq!(src.layout.size, dest_layout.size); diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index d56674f8bdbc3..f67ec17238729 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -302,7 +302,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let r = self.force_bits(right.to_scalar()?, right.layout.size)?; self.binary_int_op(bin_op, l, left.layout, r, right.layout) } - _ if left.layout.ty.is_unsafe_ptr() || left.layout.ty.is_fn_ptr() => { + _ if left.layout.ty.is_any_ptr() => { // The RHS type must be the same *or an integer type* (for `Offset`) assert!( right.layout.ty == left.layout.ty || right.layout.ty.is_integral(), diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.rs b/src/test/ui/consts/const-eval/match-test-ptr-null.rs index 9c930221e73e3..5b89b0262aca5 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.rs +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.rs @@ -1,4 +1,3 @@ - fn main() { // Make sure match uses the usual pointer comparison code path -- i.e., it should complain // that pointer comparison is disallowed, not that parts of a pointer are accessed as raw From b4372e4055887d0caf149ad2f072f5d9004efb8e Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Jul 2019 09:08:00 +0200 Subject: [PATCH 19/22] trailing full stops Co-Authored-By: Mazdak Farrokhzad --- src/librustc_mir/interpret/cast.rs | 2 +- src/librustc_mir/interpret/operator.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustc_mir/interpret/cast.rs b/src/librustc_mir/interpret/cast.rs index 16fb083b7fc2f..ac146eaaf25a6 100644 --- a/src/librustc_mir/interpret/cast.rs +++ b/src/librustc_mir/interpret/cast.rs @@ -110,7 +110,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { ) } - // Handle cast from a univariant (ZST) enum + // Handle cast from a univariant (ZST) enum. match src.layout.variants { layout::Variants::Single { index } => { if let Some(discr) = diff --git a/src/librustc_mir/interpret/operator.rs b/src/librustc_mir/interpret/operator.rs index f67ec17238729..a893f8012db99 100644 --- a/src/librustc_mir/interpret/operator.rs +++ b/src/librustc_mir/interpret/operator.rs @@ -303,7 +303,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { self.binary_int_op(bin_op, l, left.layout, r, right.layout) } _ if left.layout.ty.is_any_ptr() => { - // The RHS type must be the same *or an integer type* (for `Offset`) + // The RHS type must be the same *or an integer type* (for `Offset`). assert!( right.layout.ty == left.layout.ty || right.layout.ty.is_integral(), "Unexpected types for BinOp: {:?} {:?} {:?}", From c05155e5626e79ab0bd17626552d3eb83a8290b0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Jul 2019 09:11:53 +0200 Subject: [PATCH 20/22] bless all the things --- src/test/ui/consts/const-eval/match-test-ptr-null.stderr | 8 ++++---- src/test/ui/issues/issue-52023-array-size-pointer-cast.rs | 2 +- .../ui/issues/issue-52023-array-size-pointer-cast.stderr | 6 ++---- 3 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr index 9bb561f31ebb0..3d34ac4266270 100644 --- a/src/test/ui/consts/const-eval/match-test-ptr-null.stderr +++ b/src/test/ui/consts/const-eval/match-test-ptr-null.stderr @@ -1,5 +1,5 @@ error[E0658]: casting pointers to integers in constants is unstable - --> $DIR/match-test-ptr-null.rs:7:15 + --> $DIR/match-test-ptr-null.rs:6:15 | LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -8,19 +8,19 @@ LL | match &1 as *const i32 as usize { = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable error[E0019]: constant contains unimplemented expression type - --> $DIR/match-test-ptr-null.rs:7:15 + --> $DIR/match-test-ptr-null.rs:6:15 | LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0019]: constant contains unimplemented expression type - --> $DIR/match-test-ptr-null.rs:11:13 + --> $DIR/match-test-ptr-null.rs:10:13 | LL | 0 => 42, | ^ error[E0080]: evaluation of constant value failed - --> $DIR/match-test-ptr-null.rs:7:15 + --> $DIR/match-test-ptr-null.rs:6:15 | LL | match &1 as *const i32 as usize { | ^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants diff --git a/src/test/ui/issues/issue-52023-array-size-pointer-cast.rs b/src/test/ui/issues/issue-52023-array-size-pointer-cast.rs index 63f1128f10642..d12b483ba4473 100644 --- a/src/test/ui/issues/issue-52023-array-size-pointer-cast.rs +++ b/src/test/ui/issues/issue-52023-array-size-pointer-cast.rs @@ -1,4 +1,4 @@ fn main() { let _ = [0; (&0 as *const i32) as usize]; //~ ERROR casting pointers to integers in constants - //~^ ERROR it is undefined behavior to use this value + //~^ ERROR evaluation of constant value failed } diff --git a/src/test/ui/issues/issue-52023-array-size-pointer-cast.stderr b/src/test/ui/issues/issue-52023-array-size-pointer-cast.stderr index 2db6f42405c17..68ee53754161c 100644 --- a/src/test/ui/issues/issue-52023-array-size-pointer-cast.stderr +++ b/src/test/ui/issues/issue-52023-array-size-pointer-cast.stderr @@ -7,13 +7,11 @@ LL | let _ = [0; (&0 as *const i32) as usize]; = note: for more information, see https://github.com/rust-lang/rust/issues/51910 = help: add `#![feature(const_raw_ptr_to_usize_cast)]` to the crate attributes to enable -error[E0080]: it is undefined behavior to use this value +error[E0080]: evaluation of constant value failed --> $DIR/issue-52023-array-size-pointer-cast.rs:2:17 | LL | let _ = [0; (&0 as *const i32) as usize]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes - | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ "pointer-to-integer cast" needs an rfc before being allowed inside constants error: aborting due to 2 previous errors From 42aedecdf5174c89eeff3db198742f0200c23ac4 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 25 Jul 2019 10:47:11 +0200 Subject: [PATCH 21/22] const_prop no longer does ptr-to-int casts --- src/test/mir-opt/const_prop/reify_fn_ptr.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/test/mir-opt/const_prop/reify_fn_ptr.rs b/src/test/mir-opt/const_prop/reify_fn_ptr.rs index 809eb19ade899..7e36b2a6b1b39 100644 --- a/src/test/mir-opt/const_prop/reify_fn_ptr.rs +++ b/src/test/mir-opt/const_prop/reify_fn_ptr.rs @@ -19,7 +19,7 @@ fn main() { // _3 = const Scalar(AllocId(1).0x0) : fn(); // _2 = move _3 as usize (Misc); // ... -// _1 = const Scalar(AllocId(1).0x0) : *const fn(); +// _1 = move _2 as *const fn() (Misc); // ... // } // END rustc.main.ConstProp.after.mir From 12a29d97e2f00fb4fb79d2a7313dbfa45d921644 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 1 Aug 2019 09:12:48 +0200 Subject: [PATCH 22/22] fix rebase fallout --- src/test/ui/consts/issue-51559.rs | 2 +- src/test/ui/consts/issue-51559.stderr | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/src/test/ui/consts/issue-51559.rs b/src/test/ui/consts/issue-51559.rs index 429947269385b..69f0d8df0aa4a 100644 --- a/src/test/ui/consts/issue-51559.rs +++ b/src/test/ui/consts/issue-51559.rs @@ -2,6 +2,6 @@ const BAR: *mut () = ((|| 3) as fn() -> i32) as *mut (); pub const FOO: usize = unsafe { BAR as usize }; -//~^ ERROR it is undefined behavior to use this value +//~^ ERROR any use of this value will cause an error fn main() {} diff --git a/src/test/ui/consts/issue-51559.stderr b/src/test/ui/consts/issue-51559.stderr index 917c54ddaef1e..4d50ec818bce7 100644 --- a/src/test/ui/consts/issue-51559.stderr +++ b/src/test/ui/consts/issue-51559.stderr @@ -1,11 +1,12 @@ -error[E0080]: it is undefined behavior to use this value - --> $DIR/issue-51559.rs:4:1 +error: any use of this value will cause an error + --> $DIR/issue-51559.rs:4:33 | LL | pub const FOO: usize = unsafe { BAR as usize }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered a pointer, but expected initialized plain (non-pointer) bytes + | --------------------------------^^^^^^^^^^^^--- + | | + | "pointer-to-integer cast" needs an rfc before being allowed inside constants | - = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior + = note: `#[deny(const_err)]` on by default error: aborting due to previous error -For more information about this error, try `rustc --explain E0080`.