diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-01-30 02:42:33 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2020-02-13 10:39:23 +0100 |
| commit | e839b2ec849246ec5efe5069c8d874dbef289462 (patch) | |
| tree | 36489d29fe26c85fd9f283335acfb37d4915ee40 /src | |
| parent | 2e6eaceedeeda764056eb0e2134735793533770d (diff) | |
| download | rust-e839b2ec849246ec5efe5069c8d874dbef289462.tar.gz rust-e839b2ec849246ec5efe5069c8d874dbef289462.zip | |
Constness -> enum Const { Yes(Span), No }
Same idea for `Unsafety` & use new span for better diagnostics.
Diffstat (limited to 'src')
40 files changed, 238 insertions, 212 deletions
diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs index 1255728de37..3ab87ce8eb4 100644 --- a/src/librustc/traits/auto_trait.rs +++ b/src/librustc/traits/auto_trait.rs @@ -9,7 +9,6 @@ use crate::ty::fold::TypeFolder; use crate::ty::{Region, RegionVid}; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; -use syntax::ast; use std::collections::hash_map::Entry; use std::collections::VecDeque; @@ -350,7 +349,7 @@ impl AutoTraitFinder<'tcx> { already_visited.remove(&pred); self.add_user_pred( &mut user_computed_preds, - ty::Predicate::Trait(pred, ast::Constness::NotConst), + ty::Predicate::Trait(pred, hir::Constness::NotConst), ); predicates.push_back(pred); } else { diff --git a/src/librustc/traits/error_reporting/mod.rs b/src/librustc/traits/error_reporting/mod.rs index a7a2b578b82..c25b392ec23 100644 --- a/src/librustc/traits/error_reporting/mod.rs +++ b/src/librustc/traits/error_reporting/mod.rs @@ -695,7 +695,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { let unit_obligation = Obligation { predicate: ty::Predicate::Trait( predicate, - ast::Constness::NotConst, + hir::Constness::NotConst, ), ..obligation.clone() }; diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index bf82d743c2b..1fe8ab58d15 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -40,19 +40,19 @@ use crate::ty::fast_reject; use crate::ty::relate::TypeRelation; use crate::ty::subst::{Subst, SubstsRef}; use crate::ty::{self, ToPolyTraitRef, ToPredicate, Ty, TyCtxt, TypeFoldable, WithConstness}; -use rustc_hir::def_id::DefId; - use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir as hir; +use rustc_hir::def_id::DefId; use rustc_index::bit_set::GrowableBitSet; use rustc_span::symbol::sym; use rustc_target::spec::abi::Abi; +use syntax::attr; + use std::cell::{Cell, RefCell}; use std::cmp; use std::fmt::{self, Display}; use std::iter; use std::rc::Rc; -use syntax::{ast, attr}; pub use rustc::traits::types::select::*; @@ -677,7 +677,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> { // if the regions match exactly. let cycle = stack.iter().skip(1).take_while(|s| s.depth >= cycle_depth); let cycle = cycle.map(|stack| { - ty::Predicate::Trait(stack.obligation.predicate, ast::Constness::NotConst) + ty::Predicate::Trait(stack.obligation.predicate, hir::Constness::NotConst) }); if self.coinductive_match(cycle) { debug!("evaluate_stack({:?}) --> recursive, coinductive", stack.fresh_trait_ref); diff --git a/src/librustc/ty/fold.rs b/src/librustc/ty/fold.rs index 0dddca98c62..1f007b970b0 100644 --- a/src/librustc/ty/fold.rs +++ b/src/librustc/ty/fold.rs @@ -32,6 +32,7 @@ //! looking for, and does not need to visit anything else. use crate::ty::{self, flags::FlagComputation, Binder, Ty, TyCtxt, TypeFlags}; +use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_data_structures::fx::FxHashSet; @@ -150,7 +151,7 @@ pub trait TypeFoldable<'tcx>: fmt::Debug + Clone { } } -impl TypeFoldable<'tcx> for syntax::ast::Constness { +impl TypeFoldable<'tcx> for hir::Constness { fn super_fold_with<F: TypeFolder<'tcx>>(&self, _: &mut F) -> Self { *self } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 393d49a4e4b..2bda99e6d20 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -35,7 +35,7 @@ use rustc_data_structures::sync::{self, par_iter, Lrc, ParallelIterator}; use rustc_hir as hir; use rustc_hir::def::{CtorKind, CtorOf, DefKind, Res}; use rustc_hir::def_id::{CrateNum, DefId, DefIdMap, LocalDefId, CRATE_DEF_INDEX, LOCAL_CRATE}; -use rustc_hir::{GlobMap, Node, TraitMap}; +use rustc_hir::{Constness, GlobMap, Node, TraitMap}; use rustc_index::vec::{Idx, IndexVec}; use rustc_macros::HashStable; use rustc_serialize::{self, Encodable, Encoder}; @@ -43,7 +43,7 @@ use rustc_span::hygiene::ExpnId; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use rustc_target::abi::Align; -use syntax::ast::{self, Constness, Ident, Name}; +use syntax::ast::{self, Ident, Name}; use syntax::node_id::{NodeId, NodeMap, NodeSet}; use std::cell::RefCell; diff --git a/src/librustc/ty/print/pretty.rs b/src/librustc/ty/print/pretty.rs index 274482cba64..38442295636 100644 --- a/src/librustc/ty/print/pretty.rs +++ b/src/librustc/ty/print/pretty.rs @@ -1818,7 +1818,7 @@ define_print_and_forward_display! { ty::Predicate<'tcx> { match *self { ty::Predicate::Trait(ref data, constness) => { - if let ast::Constness::Const = constness { + if let hir::Constness::Const = constness { p!(write("const ")); } p!(print(data)) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index acd6c959751..59dd41e9d56 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -7,6 +7,7 @@ use crate::mir::ProjectionKind; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; use crate::ty::{self, InferConst, Lift, Ty, TyCtxt}; +use rustc_hir as hir; use rustc_hir::def::Namespace; use rustc_hir::def_id::CRATE_DEF_INDEX; use rustc_index::vec::{Idx, IndexVec}; @@ -15,7 +16,6 @@ use smallvec::SmallVec; use std::fmt; use std::rc::Rc; use std::sync::Arc; -use syntax::ast; impl fmt::Debug for ty::GenericParamDef { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { @@ -236,7 +236,7 @@ impl fmt::Debug for ty::Predicate<'tcx> { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { match *self { ty::Predicate::Trait(ref a, constness) => { - if let ast::Constness::Const = constness { + if let hir::Constness::Const = constness { write!(f, "const ")?; } a.fmt(f) diff --git a/src/librustc_ast_lowering/item.rs b/src/librustc_ast_lowering/item.rs index dab950e23f6..8cc3479dd1b 100644 --- a/src/librustc_ast_lowering/item.rs +++ b/src/librustc_ast_lowering/item.rs @@ -67,10 +67,12 @@ impl<'a> Visitor<'a> for ItemLowerer<'a, '_, '_> { self.lctx.with_parent_item_lifetime_defs(hir_id, |this| { let this = &mut ItemLowerer { lctx: this }; if let ItemKind::Impl { constness, ref of_trait, .. } = item.kind { - if constness == Constness::Const { + if let Const::Yes(span) = constness { this.lctx .diagnostic() - .span_err(item.span, "const trait impls are not yet implemented"); + .struct_span_err(item.span, "const trait impls are not yet implemented") + .span_label(span, "const because of this") + .emit(); } this.with_trait_impl_ref(of_trait, |this| visit::walk_item(this, item)); @@ -413,10 +415,10 @@ impl<'hir> LoweringContext<'_, 'hir> { }); hir::ItemKind::Impl { - unsafety, + unsafety: self.lower_unsafety(unsafety), polarity, defaultness: self.lower_defaultness(defaultness, true /* [1] */), - constness, + constness: self.lower_constness(constness), generics, of_trait: trait_ref, self_ty: lowered_ty, @@ -430,7 +432,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .alloc_from_iter(items.iter().map(|item| self.lower_trait_item_ref(item))); hir::ItemKind::Trait( is_auto, - unsafety, + self.lower_unsafety(unsafety), self.lower_generics(generics, ImplTraitContext::disallowed()), bounds, items, @@ -1245,9 +1247,9 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_fn_header(&mut self, h: FnHeader) -> hir::FnHeader { hir::FnHeader { - unsafety: h.unsafety, + unsafety: self.lower_unsafety(h.unsafety), asyncness: self.lower_asyncness(h.asyncness.node), - constness: h.constness.node, + constness: self.lower_constness(h.constness), abi: self.lower_extern(h.ext), } } @@ -1281,6 +1283,20 @@ impl<'hir> LoweringContext<'_, 'hir> { } } + fn lower_constness(&mut self, c: Const) -> hir::Constness { + match c { + Const::Yes(_) => hir::Constness::Const, + Const::No => hir::Constness::NotConst, + } + } + + pub(super) fn lower_unsafety(&mut self, u: Unsafe) -> hir::Unsafety { + match u { + Unsafe::Yes(_) => hir::Unsafety::Unsafe, + Unsafe::No => hir::Unsafety::Normal, + } + } + pub(super) fn lower_generics_mut( &mut self, generics: &Generics, diff --git a/src/librustc_ast_lowering/lib.rs b/src/librustc_ast_lowering/lib.rs index 5816a64fca5..618b1e7964b 100644 --- a/src/librustc_ast_lowering/lib.rs +++ b/src/librustc_ast_lowering/lib.rs @@ -1196,7 +1196,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { &NodeMap::default(), ImplTraitContext::disallowed(), ), - unsafety: f.unsafety, + unsafety: this.lower_unsafety(f.unsafety), abi: this.lower_extern(f.ext), decl: this.lower_fn_decl(&f.decl, None, false, None), param_names: this.lower_fn_params_to_names(&f.decl), diff --git a/src/librustc_ast_passes/ast_validation.rs b/src/librustc_ast_passes/ast_validation.rs index 057acec9598..de4f092dbf0 100644 --- a/src/librustc_ast_passes/ast_validation.rs +++ b/src/librustc_ast_passes/ast_validation.rs @@ -13,7 +13,6 @@ use rustc_parse::validate_attr; use rustc_session::lint::builtin::PATTERNS_IN_FNS_WITHOUT_BODY; use rustc_session::lint::LintBuffer; use rustc_session::Session; -use rustc_span::source_map::Spanned; use rustc_span::symbol::{kw, sym}; use rustc_span::Span; use std::mem; @@ -234,16 +233,11 @@ impl<'a> AstValidator<'a> { } } - fn check_trait_fn_not_const(&self, constness: Spanned<Constness>) { - if constness.node == Constness::Const { - struct_span_err!( - self.session, - constness.span, - E0379, - "trait fns cannot be declared const" - ) - .span_label(constness.span, "trait fns cannot be const") - .emit(); + fn check_trait_fn_not_const(&self, constness: Const) { + if let Const::Yes(span) = constness { + struct_span_err!(self.session, span, E0379, "trait fns cannot be declared const") + .span_label(span, "trait fns cannot be const") + .emit(); } } @@ -487,7 +481,7 @@ impl<'a> AstValidator<'a> { (Some(FnCtxt::Foreign), _) => return, (Some(FnCtxt::Free), Some(header)) => match header.ext { Extern::Explicit(StrLit { symbol_unescaped: sym::C, .. }) | Extern::Implicit - if header.unsafety == Unsafety::Unsafe => + if matches!(header.unsafety, Unsafe::Yes(_)) => { return; } @@ -514,12 +508,13 @@ impl<'a> AstValidator<'a> { /// FIXME(const_generics): Is this really true / necessary? Discuss with @varkor. /// At any rate, the restriction feels too syntactic. Consider moving it to e.g. typeck. fn check_const_fn_const_generic(&self, span: Span, sig: &FnSig, generics: &Generics) { - if sig.header.constness.node == Constness::Const { + if let Const::Yes(const_span) = sig.header.constness { // Look for const generics and error if we find any. for param in &generics.params { if let GenericParamKind::Const { .. } = param.kind { self.err_handler() .struct_span_err(span, "const parameters are not permitted in `const fn`") + .span_label(const_span, "`const fn` because of this") .emit(); } } @@ -754,13 +749,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .help("use `auto trait Trait {}` instead") .emit(); } - if unsafety == Unsafety::Unsafe && polarity == ImplPolarity::Negative { + if let (Unsafe::Yes(span), ImplPolarity::Negative) = (unsafety, polarity) { struct_span_err!( this.session, item.span, E0198, "negative impls cannot be unsafe" ) + .span_label(span, "unsafe because of this") .emit(); } @@ -782,13 +778,14 @@ impl<'a> Visitor<'a> for AstValidator<'a> { &item.vis, Some("place qualifiers on individual impl items instead"), ); - if unsafety == Unsafety::Unsafe { + if let Unsafe::Yes(span) = unsafety { struct_span_err!( self.session, item.span, E0197, "inherent impls cannot be unsafe" ) + .span_label(span, "unsafe because of this") .emit(); } if polarity == ImplPolarity::Negative { @@ -800,9 +797,10 @@ impl<'a> Visitor<'a> for AstValidator<'a> { .note("only trait implementations may be annotated with default") .emit(); } - if constness == Constness::Const { + if let Const::Yes(span) = constness { self.err_handler() .struct_span_err(item.span, "inherent impls cannot be `const`") + .span_label(span, "`const` because of this") .note("only trait implementations may be annotated with `const`") .emit(); } diff --git a/src/librustc_ast_passes/feature_gate.rs b/src/librustc_ast_passes/feature_gate.rs index a10ac94d894..cfab54925b1 100644 --- a/src/librustc_ast_passes/feature_gate.rs +++ b/src/librustc_ast_passes/feature_gate.rs @@ -538,8 +538,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { match i.kind { ast::AssocItemKind::Fn(ref sig, _) => { - let constness = sig.header.constness.node; - if let (ast::Constness::Const, AssocCtxt::Trait) = (constness, ctxt) { + if let (ast::Const::Yes(_), AssocCtxt::Trait) = (sig.header.constness, ctxt) { gate_feature_post!(&self, const_fn, i.span, "const fn is unstable"); } } diff --git a/src/librustc_ast_pretty/pprust.rs b/src/librustc_ast_pretty/pprust.rs index 78bf149f0e0..633964683dc 100644 --- a/src/librustc_ast_pretty/pprust.rs +++ b/src/librustc_ast_pretty/pprust.rs @@ -2686,7 +2686,7 @@ impl<'a> State<'a> { crate fn print_ty_fn( &mut self, ext: ast::Extern, - unsafety: ast::Unsafety, + unsafety: ast::Unsafe, decl: &ast::FnDecl, name: Option<ast::Ident>, generic_params: &[ast::GenericParam], @@ -2733,11 +2733,7 @@ impl<'a> State<'a> { crate fn print_fn_header_info(&mut self, header: ast::FnHeader, vis: &ast::Visibility) { self.s.word(visibility_qualified(vis, "")); - match header.constness.node { - ast::Constness::NotConst => {} - ast::Constness::Const => self.word_nbsp("const"), - } - + self.print_constness(header.constness); self.print_asyncness(header.asyncness.node); self.print_unsafety(header.unsafety); @@ -2756,17 +2752,17 @@ impl<'a> State<'a> { self.s.word("fn") } - crate fn print_unsafety(&mut self, s: ast::Unsafety) { + crate fn print_unsafety(&mut self, s: ast::Unsafe) { match s { - ast::Unsafety::Normal => {} - ast::Unsafety::Unsafe => self.word_nbsp("unsafe"), + ast::Unsafe::No => {} + ast::Unsafe::Yes(_) => self.word_nbsp("unsafe"), } } - crate fn print_constness(&mut self, s: ast::Constness) { + crate fn print_constness(&mut self, s: ast::Const) { match s { - ast::Constness::Const => self.word_nbsp("const"), - ast::Constness::NotConst => {} + ast::Const::No => {} + ast::Const::Yes(_) => self.word_nbsp("const"), } } diff --git a/src/librustc_builtin_macros/deriving/generic/mod.rs b/src/librustc_builtin_macros/deriving/generic/mod.rs index f99008a6d5c..5cf233e222e 100644 --- a/src/librustc_builtin_macros/deriving/generic/mod.rs +++ b/src/librustc_builtin_macros/deriving/generic/mod.rs @@ -700,7 +700,7 @@ impl<'a> TraitDef<'a> { let mut a = vec![attr, unused_qual]; a.extend(self.attributes.iter().cloned()); - let unsafety = if self.is_unsafe { ast::Unsafety::Unsafe } else { ast::Unsafety::Normal }; + let unsafety = if self.is_unsafe { ast::Unsafe::Yes(self.span) } else { ast::Unsafe::No }; cx.item( self.span, @@ -710,7 +710,7 @@ impl<'a> TraitDef<'a> { unsafety, polarity: ast::ImplPolarity::Positive, defaultness: ast::Defaultness::Final, - constness: ast::Constness::NotConst, + constness: ast::Const::No, generics: trait_generics, of_trait: opt_trait_ref, self_ty: self_type, @@ -960,7 +960,7 @@ impl<'a> MethodDef<'a> { let fn_decl = cx.fn_decl(args, ast::FunctionRetTy::Ty(ret_type)); let body_block = cx.block_expr(body); - let unsafety = if self.is_unsafe { ast::Unsafety::Unsafe } else { ast::Unsafety::Normal }; + let unsafety = if self.is_unsafe { ast::Unsafe::Yes(trait_.span) } else { ast::Unsafe::No }; let trait_lo_sp = trait_.span.shrink_to_lo(); diff --git a/src/librustc_builtin_macros/deriving/mod.rs b/src/librustc_builtin_macros/deriving/mod.rs index 914dcdf1969..63cd03527e1 100644 --- a/src/librustc_builtin_macros/deriving/mod.rs +++ b/src/librustc_builtin_macros/deriving/mod.rs @@ -157,10 +157,10 @@ fn inject_impl_of_structural_trait( ast::Ident::invalid(), attrs, ItemKind::Impl { - unsafety: ast::Unsafety::Normal, + unsafety: ast::Unsafe::No, polarity: ast::ImplPolarity::Positive, defaultness: ast::Defaultness::Final, - constness: ast::Constness::NotConst, + constness: ast::Const::No, generics, of_trait: Some(trait_ref), self_ty: self_type, diff --git a/src/librustc_builtin_macros/global_allocator.rs b/src/librustc_builtin_macros/global_allocator.rs index ec0d55b38a7..52f033e8b14 100644 --- a/src/librustc_builtin_macros/global_allocator.rs +++ b/src/librustc_builtin_macros/global_allocator.rs @@ -4,7 +4,7 @@ use rustc_expand::base::{Annotatable, ExtCtxt}; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; use syntax::ast::{self, Attribute, Expr, FnHeader, FnSig, Generics, Ident, Param}; -use syntax::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafety}; +use syntax::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafe}; use syntax::expand::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; use syntax::ptr::P; @@ -64,7 +64,7 @@ impl AllocFnFactory<'_, '_> { let result = self.call_allocator(method.name, args); let (output_ty, output_expr) = self.ret_ty(&method.output, result); let decl = self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)); - let header = FnHeader { unsafety: Unsafety::Unsafe, ..FnHeader::default() }; + let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() }; let sig = FnSig { decl, header }; let kind = ItemKind::Fn(sig, Generics::default(), Some(self.cx.block_expr(output_expr))); let item = self.cx.item( diff --git a/src/librustc_builtin_macros/test.rs b/src/librustc_builtin_macros/test.rs index 2d6ff81aea8..dd93596b3cf 100644 --- a/src/librustc_builtin_macros/test.rs +++ b/src/librustc_builtin_macros/test.rs @@ -375,8 +375,10 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic); let ref sd = cx.parse_sess.span_diagnostic; if let ast::ItemKind::Fn(ref sig, ref generics, _) = i.kind { - if sig.header.unsafety == ast::Unsafety::Unsafe { - sd.span_err(i.span, "unsafe functions cannot be used for tests"); + if let ast::Unsafe::Yes(span) = sig.header.unsafety { + sd.struct_span_err(i.span, "unsafe functions cannot be used for tests") + .span_label(span, "unsafe because of this") + .emit(); return false; } if sig.header.asyncness.node.is_async() { diff --git a/src/librustc_hir/hir.rs b/src/librustc_hir/hir.rs index 27bca1625c1..c2ddaf7df31 100644 --- a/src/librustc_hir/hir.rs +++ b/src/librustc_hir/hir.rs @@ -19,7 +19,7 @@ use rustc_target::spec::abi::Abi; use syntax::ast::{self, AsmDialect, CrateSugar, Ident, Name, NodeId}; use syntax::ast::{AttrVec, Attribute, FloatTy, IntTy, Label, LitKind, StrStyle, UintTy}; pub use syntax::ast::{BorrowKind, ImplPolarity, IsAuto}; -pub use syntax::ast::{CaptureBy, Constness, Movability, Mutability, Unsafety}; +pub use syntax::ast::{CaptureBy, Movability, Mutability}; use syntax::node_id::NodeMap; use syntax::tokenstream::TokenStream; use syntax::util::parser::ExprPrecedence; @@ -2109,18 +2109,8 @@ impl ImplicitSelfKind { } } -#[derive( - Copy, - Clone, - PartialEq, - Eq, - PartialOrd, - HashStable_Generic, - Ord, - RustcEncodable, - RustcDecodable, - Debug -)] +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, RustcEncodable, RustcDecodable, Debug)] +#[derive(HashStable_Generic)] pub enum IsAsync { Async, NotAsync, @@ -2389,6 +2379,38 @@ pub struct Item<'hir> { pub span: Span, } +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)] +pub enum Unsafety { + Unsafe, + Normal, +} + +impl Unsafety { + pub fn prefix_str(&self) -> &'static str { + match self { + Self::Unsafe => "unsafe ", + Self::Normal => "", + } + } +} + +impl fmt::Display for Unsafety { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.write_str(match *self { + Self::Unsafe => "unsafe", + Self::Normal => "normal", + }) + } +} + +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Debug)] +#[derive(RustcEncodable, RustcDecodable, HashStable_Generic)] +pub enum Constness { + Const, + NotConst, +} + #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] pub struct FnHeader { pub unsafety: Unsafety, diff --git a/src/librustc_hir/print.rs b/src/librustc_hir/print.rs index 071c3de4b1c..b31b814d67b 100644 --- a/src/librustc_hir/print.rs +++ b/src/librustc_hir/print.rs @@ -648,7 +648,7 @@ impl<'a> State<'a> { self.s.space(); } - if constness == ast::Constness::Const { + if let hir::Constness::Const = constness { self.word_nbsp("const"); } diff --git a/src/librustc_interface/util.rs b/src/librustc_interface/util.rs index 3052c9fc26f..659323d1c25 100644 --- a/src/librustc_interface/util.rs +++ b/src/librustc_interface/util.rs @@ -668,7 +668,7 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> { } fn is_sig_const(sig: &ast::FnSig) -> bool { - sig.header.constness.node == ast::Constness::Const + matches!(sig.header.constness, ast::Const::Yes(_)) || ReplaceBodyWithLoop::should_ignore_fn(&sig.decl.output) } } diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index c827a7f3d52..93fca43d67c 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -258,13 +258,13 @@ impl EarlyLintPass for UnsafeCode { fn check_item(&mut self, cx: &EarlyContext<'_>, it: &ast::Item) { match it.kind { - ast::ItemKind::Trait(_, ast::Unsafety::Unsafe, ..) => { + ast::ItemKind::Trait(_, ast::Unsafe::Yes(_), ..) => { self.report_unsafe(cx, it.span, |lint| { lint.build("declaration of an `unsafe` trait").emit() }) } - ast::ItemKind::Impl { unsafety: ast::Unsafety::Unsafe, .. } => { + ast::ItemKind::Impl { unsafety: ast::Unsafe::Yes(_), .. } => { self.report_unsafe(cx, it.span, |lint| { lint.build("implementation of an `unsafe` trait").emit() }) @@ -278,7 +278,7 @@ impl EarlyLintPass for UnsafeCode { if let FnKind::Fn( ctxt, _, - ast::FnSig { header: ast::FnHeader { unsafety: ast::Unsafety::Unsafe, .. }, .. }, + ast::FnSig { header: ast::FnHeader { unsafety: ast::Unsafe::Yes(_), .. }, .. }, _, body, ) = fk diff --git a/src/librustc_mir/borrow_check/type_check/mod.rs b/src/librustc_mir/borrow_check/type_check/mod.rs index 100fd7dc48d..4cbe4145589 100644 --- a/src/librustc_mir/borrow_check/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/type_check/mod.rs @@ -32,7 +32,6 @@ use rustc_hir as hir; use rustc_hir::def_id::DefId; use rustc_index::vec::{Idx, IndexVec}; use rustc_span::{Span, DUMMY_SP}; -use syntax::ast; use crate::dataflow::generic::ResultsCursor; use crate::dataflow::move_paths::MoveData; @@ -1938,7 +1937,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { tcx.mk_substs_trait(ty, &[]), ), }), - ast::Constness::NotConst, + hir::Constness::NotConst, ), ), &traits::SelectionError::Unimplemented, @@ -2579,7 +2578,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> { self.prove_predicates( Some(ty::Predicate::Trait( trait_ref.to_poly_trait_ref().to_poly_trait_predicate(), - ast::Constness::NotConst, + hir::Constness::NotConst, )), locations, category, diff --git a/src/librustc_mir/transform/qualify_min_const_fn.rs b/src/librustc_mir/transform/qualify_min_const_fn.rs index 6a68ccdddff..b12f4ce3269 100644 --- a/src/librustc_mir/transform/qualify_min_const_fn.rs +++ b/src/librustc_mir/transform/qualify_min_const_fn.rs @@ -6,7 +6,6 @@ use rustc_hir::def_id::DefId; use rustc_span::symbol::{sym, Symbol}; use rustc_span::Span; use std::borrow::Cow; -use syntax::ast; type McfResult = Result<(), (Span, Cow<'static, str>)>; @@ -35,7 +34,7 @@ pub fn is_min_const_fn(tcx: TyCtxt<'tcx>, def_id: DefId, body: &'a Body<'tcx>) - match pred.skip_binder().self_ty().kind { ty::Param(ref p) => { // Allow `T: ?const Trait` - if *constness == ast::Constness::NotConst + if *constness == hir::Constness::NotConst && feature_allowed(tcx, def_id, sym::const_trait_bound_opt_out) { continue; diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs index 07d8bae4725..a66a85b2b83 100644 --- a/src/librustc_parse/parser/item.rs +++ b/src/librustc_parse/parser/item.rs @@ -12,7 +12,7 @@ use rustc_span::BytePos; use syntax::ast::{self, AttrKind, AttrStyle, AttrVec, Attribute, Ident, DUMMY_NODE_ID}; use syntax::ast::{AssocItem, AssocItemKind, Item, ItemKind, UseTree, UseTreeKind}; use syntax::ast::{BindingMode, Block, FnDecl, FnSig, Mac, MacArgs, MacDelimiter, Param, SelfKind}; -use syntax::ast::{Constness, Defaultness, Extern, IsAsync, IsAuto, PathSegment, StrLit, Unsafety}; +use syntax::ast::{Const, Defaultness, Extern, IsAsync, IsAuto, PathSegment, StrLit, Unsafe}; use syntax::ast::{EnumDef, Generics, StructField, TraitRef, Ty, TyKind, Variant, VariantData}; use syntax::ast::{FnHeader, ForeignItem, ForeignItemKind, Mutability, Visibility, VisibilityKind}; use syntax::ptr::P; @@ -107,9 +107,9 @@ impl<'a> Parser<'a> { // EXTERN FUNCTION ITEM let fn_span = self.prev_span; let header = FnHeader { - unsafety: Unsafety::Normal, + unsafety: Unsafe::No, asyncness: respan(fn_span, IsAsync::NotAsync), - constness: respan(fn_span, Constness::NotConst), + constness: Const::No, ext: Extern::from_abi(abi), }; return self.parse_item_fn(lo, vis, attrs, header); @@ -128,8 +128,8 @@ impl<'a> Parser<'a> { return self.mk_item_with_info(attrs, lo, vis, info); } - if self.eat_keyword(kw::Const) { - let const_span = self.prev_span; + let constness = self.parse_constness(); + if let Const::Yes(const_span) = constness { if [kw::Fn, kw::Unsafe, kw::Extern].iter().any(|k| self.check_keyword(*k)) { // CONST FUNCTION ITEM let unsafety = self.parse_unsafety(); @@ -143,7 +143,7 @@ impl<'a> Parser<'a> { let header = FnHeader { unsafety, asyncness: respan(const_span, IsAsync::NotAsync), - constness: respan(const_span, Constness::Const), + constness, ext, }; return self.parse_item_fn(lo, vis, attrs, header); @@ -175,7 +175,6 @@ impl<'a> Parser<'a> { self.bump(); // `async` let unsafety = self.parse_unsafety(); // `unsafe`? self.expect_keyword(kw::Fn)?; // `fn` - let fn_span = self.prev_span; let asyncness = respan( async_span, IsAsync::Async { @@ -184,20 +183,16 @@ impl<'a> Parser<'a> { }, ); self.ban_async_in_2015(async_span); - let header = FnHeader { - unsafety, - asyncness, - constness: respan(fn_span, Constness::NotConst), - ext: Extern::None, - }; + let header = + FnHeader { unsafety, asyncness, constness: Const::No, ext: Extern::None }; return self.parse_item_fn(lo, vis, attrs, header); } } if self.check_keyword(kw::Unsafe) && self.is_keyword_ahead(1, &[kw::Trait, kw::Auto]) { // UNSAFE TRAIT ITEM - self.bump(); // `unsafe` - let info = self.parse_item_trait(lo, Unsafety::Unsafe)?; + let unsafety = self.parse_unsafety(); + let info = self.parse_item_trait(lo, unsafety)?; return self.mk_item_with_info(attrs, lo, vis, info); } @@ -218,9 +213,9 @@ impl<'a> Parser<'a> { self.bump(); let fn_span = self.prev_span; let header = FnHeader { - unsafety: Unsafety::Normal, + unsafety: Unsafe::No, asyncness: respan(fn_span, IsAsync::NotAsync), - constness: respan(fn_span, Constness::NotConst), + constness: Const::No, ext: Extern::None, }; return self.parse_item_fn(lo, vis, attrs, header); @@ -230,16 +225,16 @@ impl<'a> Parser<'a> { && self.look_ahead(1, |t| *t != token::OpenDelim(token::Brace)) { // UNSAFE FUNCTION ITEM - self.bump(); // `unsafe` + let unsafety = self.parse_unsafety(); // `{` is also expected after `unsafe`; in case of error, include it in the diagnostic. self.check(&token::OpenDelim(token::Brace)); let ext = self.parse_extern()?; self.expect_keyword(kw::Fn)?; let fn_span = self.prev_span; let header = FnHeader { - unsafety: Unsafety::Unsafe, + unsafety, asyncness: respan(fn_span, IsAsync::NotAsync), - constness: respan(fn_span, Constness::NotConst), + constness: Const::No, ext, }; return self.parse_item_fn(lo, vis, attrs, header); @@ -268,7 +263,7 @@ impl<'a> Parser<'a> { || (self.check_keyword(kw::Auto) && self.is_keyword_ahead(1, &[kw::Trait])) { // TRAIT ITEM - let info = self.parse_item_trait(lo, Unsafety::Normal)?; + let info = self.parse_item_trait(lo, Unsafe::No)?; return self.mk_item_with_info(attrs, lo, vis, info); } @@ -547,7 +542,7 @@ impl<'a> Parser<'a> { /// `impl` GENERICS `const`? `!`? TYPE (`where` PREDICATES)? `{` BODY `}` fn parse_item_impl( &mut self, - unsafety: Unsafety, + unsafety: Unsafe, defaultness: Defaultness, ) -> PResult<'a, ItemInfo> { // First, parse generic parameters if necessary. @@ -561,13 +556,10 @@ impl<'a> Parser<'a> { generics }; - let constness = if self.eat_keyword(kw::Const) { - let span = self.prev_span; + let constness = self.parse_constness(); + if let Const::Yes(span) = constness { self.sess.gated_spans.gate(sym::const_trait_impl, span); - Constness::Const - } else { - Constness::NotConst - }; + } // Disambiguate `impl !Trait for Type { ... }` and `impl ! { ... }` for the never type. let polarity = if self.check(&token::Not) && self.look_ahead(1, |t| t.can_begin_type()) { @@ -707,7 +699,7 @@ impl<'a> Parser<'a> { } /// Parses `auto? trait Foo { ... }` or `trait Foo = Bar;`. - fn parse_item_trait(&mut self, lo: Span, unsafety: Unsafety) -> PResult<'a, ItemInfo> { + fn parse_item_trait(&mut self, lo: Span, unsafety: Unsafe) -> PResult<'a, ItemInfo> { // Parse optional `auto` prefix. let is_auto = if self.eat_keyword(kw::Auto) { IsAuto::Yes } else { IsAuto::No }; @@ -734,11 +726,11 @@ impl<'a> Parser<'a> { self.expect_semi()?; let whole_span = lo.to(self.prev_span); - if is_auto == IsAuto::Yes { + if let IsAuto::Yes = is_auto { let msg = "trait aliases cannot be `auto`"; self.struct_span_err(whole_span, msg).span_label(whole_span, msg).emit(); } - if unsafety != Unsafety::Normal { + if let Unsafe::Yes(_) = unsafety { let msg = "trait aliases cannot be `unsafe`"; self.struct_span_err(whole_span, msg).span_label(whole_span, msg).emit(); } @@ -1785,28 +1777,27 @@ impl<'a> Parser<'a> { Ok(body) } - /// Parses all the "front matter" for a `fn` declaration, up to - /// and including the `fn` keyword: + /// Parses all the "front matter" (or "qualifiers") for a `fn` declaration, + /// up to and including the `fn` keyword. The formal grammar is: /// - /// - `const fn` - /// - `unsafe fn` - /// - `const unsafe fn` - /// - `extern fn` - /// - etc. + /// ``` + /// Extern = "extern" StringLit ; + /// FnQual = "const"? "async"? "unsafe"? Extern? ; + /// FnFrontMatter = FnQual? "fn" ; + /// ``` fn parse_fn_front_matter(&mut self) -> PResult<'a, FnHeader> { - let is_const_fn = self.eat_keyword(kw::Const); - let const_span = self.prev_span; + let constness = self.parse_constness(); let asyncness = self.parse_asyncness(); if let IsAsync::Async { .. } = asyncness { self.ban_async_in_2015(self.prev_span); } let asyncness = respan(self.prev_span, asyncness); let unsafety = self.parse_unsafety(); - let (constness, unsafety, ext) = if is_const_fn { - (respan(const_span, Constness::Const), unsafety, Extern::None) + let (constness, unsafety, ext) = if let Const::Yes(_) = constness { + (constness, unsafety, Extern::None) } else { let ext = self.parse_extern()?; - (respan(self.prev_span, Constness::NotConst), unsafety, ext) + (Const::No, unsafety, ext) }; if !self.eat_keyword(kw::Fn) { // It is possible for `expect_one_of` to recover given the contents of diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs index e1461dbb8e7..bccf5968118 100644 --- a/src/librustc_parse/parser/mod.rs +++ b/src/librustc_parse/parser/mod.rs @@ -22,7 +22,8 @@ use rustc_session::parse::ParseSess; use rustc_span::source_map::respan; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::{FileName, Span, DUMMY_SP}; -use syntax::ast::{self, AttrStyle, AttrVec, CrateSugar, Extern, Ident, Unsafety, DUMMY_NODE_ID}; +use syntax::ast::DUMMY_NODE_ID; +use syntax::ast::{self, AttrStyle, AttrVec, Const, CrateSugar, Extern, Ident, Unsafe}; use syntax::ast::{IsAsync, MacArgs, MacDelimiter, Mutability, StrLit, Visibility, VisibilityKind}; use syntax::ptr::P; use syntax::token::{self, DelimToken, Token, TokenKind}; @@ -962,8 +963,13 @@ impl<'a> Parser<'a> { } /// Parses unsafety: `unsafe` or nothing. - fn parse_unsafety(&mut self) -> Unsafety { - if self.eat_keyword(kw::Unsafe) { Unsafety::Unsafe } else { Unsafety::Normal } + fn parse_unsafety(&mut self) -> Unsafe { + if self.eat_keyword(kw::Unsafe) { Unsafe::Yes(self.prev_span) } else { Unsafe::No } + } + + /// Parses constness: `const` or nothing. + fn parse_constness(&mut self) -> Const { + if self.eat_keyword(kw::Const) { Const::Yes(self.prev_span) } else { Const::No } } /// Parses mutability (`mut` or nothing). diff --git a/src/librustc_save_analysis/sig.rs b/src/librustc_save_analysis/sig.rs index 6401cabdcd5..820202c85ab 100644 --- a/src/librustc_save_analysis/sig.rs +++ b/src/librustc_save_analysis/sig.rs @@ -225,7 +225,7 @@ impl Sig for ast::Ty { text.push('>'); } - if f.unsafety == ast::Unsafety::Unsafe { + if let ast::Unsafe::Yes(_) = f.unsafety { text.push_str("unsafe "); } push_extern(&mut text, f.ext); @@ -365,13 +365,13 @@ impl Sig for ast::Item { } ast::ItemKind::Fn(ast::FnSig { ref decl, header }, ref generics, _) => { let mut text = String::new(); - if header.constness.node == ast::Constness::Const { + if let ast::Const::Yes(_) = header.constness { text.push_str("const "); } if header.asyncness.node.is_async() { text.push_str("async "); } - if header.unsafety == ast::Unsafety::Unsafe { + if let ast::Unsafe::Yes(_) = header.unsafety { text.push_str("unsafe "); } push_extern(&mut text, header.ext); @@ -453,7 +453,7 @@ impl Sig for ast::Item { text.push_str("auto "); } - if unsafety == ast::Unsafety::Unsafe { + if let ast::Unsafe::Yes(_) = unsafety { text.push_str("unsafe "); } text.push_str("trait "); @@ -496,11 +496,11 @@ impl Sig for ast::Item { if let ast::Defaultness::Default = defaultness { text.push_str("default "); } - if unsafety == ast::Unsafety::Unsafe { + if let ast::Unsafe::Yes(_) = unsafety { text.push_str("unsafe "); } text.push_str("impl"); - if constness == ast::Constness::Const { + if let ast::Const::Yes(_) = constness { text.push_str(" const"); } @@ -884,13 +884,13 @@ fn make_method_signature( ) -> Result { // FIXME code dup with function signature let mut text = String::new(); - if m.header.constness.node == ast::Constness::Const { + if let ast::Const::Yes(_) = m.header.constness { text.push_str("const "); } if m.header.asyncness.node.is_async() { text.push_str("async "); } - if m.header.unsafety == ast::Unsafety::Unsafe { + if let ast::Unsafe::Yes(_) = m.header.unsafety { text.push_str("unsafe "); } push_extern(&mut text, m.header.ext); diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index c26b47c3130..0e7c10541ca 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -28,12 +28,12 @@ use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::intravisit::Visitor; use rustc_hir::print; -use rustc_hir::{ExprKind, GenericArg, GenericArgs}; +use rustc_hir::{Constness, ExprKind, GenericArg, GenericArgs}; use rustc_span::symbol::sym; use rustc_span::{MultiSpan, Span, DUMMY_SP}; use rustc_target::spec::abi; use smallvec::SmallVec; -use syntax::ast::{self, Constness}; +use syntax::ast; use syntax::util::lev_distance::find_best_match_for_name; use std::collections::BTreeSet; @@ -1502,7 +1502,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o { .filter(|(trait_ref, _, _)| !tcx.trait_is_auto(trait_ref.def_id())); for (base_trait_ref, span, constness) in regular_traits_refs_spans { - assert_eq!(constness, ast::Constness::NotConst); + assert_eq!(constness, Constness::NotConst); for trait_ref in traits::elaborate_trait_ref(tcx, base_trait_ref) { debug!( diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index fd0c994a6ea..a825856e38a 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -2693,13 +2693,13 @@ impl<'a, 'tcx> AstConv<'tcx> for FnCtxt<'a, 'tcx> { None } - fn default_constness_for_trait_bounds(&self) -> ast::Constness { + fn default_constness_for_trait_bounds(&self) -> hir::Constness { // FIXME: refactor this into a method let node = self.tcx.hir().get(self.body_id); if let Some(fn_like) = FnLikeNode::from_node(node) { fn_like.constness() } else { - ast::Constness::NotConst + hir::Constness::NotConst } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f3a1f412d0d..5349c324ad8 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -300,11 +300,11 @@ impl AstConv<'tcx> for ItemCtxt<'tcx> { Some(self.item_def_id) } - fn default_constness_for_trait_bounds(&self) -> ast::Constness { + fn default_constness_for_trait_bounds(&self) -> hir::Constness { if let Some(fn_like) = FnLikeNode::from_node(self.node()) { fn_like.constness() } else { - ast::Constness::NotConst + hir::Constness::NotConst } } @@ -2429,7 +2429,7 @@ fn explicit_predicates_of(tcx: TyCtxt<'_>, def_id: DefId) -> ty::GenericPredicat match bound { &hir::GenericBound::Trait(ref poly_trait_ref, modifier) => { let constness = match modifier { - hir::TraitBoundModifier::MaybeConst => ast::Constness::NotConst, + hir::TraitBoundModifier::MaybeConst => hir::Constness::NotConst, hir::TraitBoundModifier::None => constness, hir::TraitBoundModifier::Maybe => bug!("this wasn't handled"), }; @@ -2617,13 +2617,13 @@ fn predicates_from_bound<'tcx>( astconv: &dyn AstConv<'tcx>, param_ty: Ty<'tcx>, bound: &'tcx hir::GenericBound<'tcx>, - constness: ast::Constness, + constness: hir::Constness, ) -> Vec<(ty::Predicate<'tcx>, Span)> { match *bound { hir::GenericBound::Trait(ref tr, modifier) => { let constness = match modifier { hir::TraitBoundModifier::Maybe => return vec![], - hir::TraitBoundModifier::MaybeConst => ast::Constness::NotConst, + hir::TraitBoundModifier::MaybeConst => hir::Constness::NotConst, hir::TraitBoundModifier::None => constness, }; diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index 474868f0dd6..067b33c1447 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -377,7 +377,7 @@ pub fn hir_trait_to_predicates<'tcx>( &item_cx, hir_trait, DUMMY_SP, - syntax::ast::Constness::NotConst, + hir::Constness::NotConst, tcx.types.err, &mut bounds, true, diff --git a/src/librustdoc/doctree.rs b/src/librustdoc/doctree.rs index 218674b757f..744201a0050 100644 --- a/src/librustdoc/doctree.rs +++ b/src/librustdoc/doctree.rs @@ -203,7 +203,7 @@ pub struct Impl<'hir> { pub unsafety: hir::Unsafety, pub polarity: hir::ImplPolarity, pub defaultness: hir::Defaultness, - pub constness: ast::Constness, + pub constness: hir::Constness, pub generics: &'hir hir::Generics<'hir>, pub trait_: &'hir Option<hir::TraitRef<'hir>>, pub for_: &'hir hir::Ty<'hir>, diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index b22406124e0..a7142dfda85 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -1863,7 +1863,7 @@ pub struct Ty { #[derive(Clone, RustcEncodable, RustcDecodable, Debug)] pub struct BareFnTy { - pub unsafety: Unsafety, + pub unsafety: Unsafe, pub ext: Extern, pub generic_params: Vec<GenericParam>, pub decl: P<FnDecl>, @@ -2101,43 +2101,11 @@ pub enum IsAuto { No, } -#[derive( - Copy, - Clone, - PartialEq, - Eq, - PartialOrd, - Ord, - Hash, - RustcEncodable, - RustcDecodable, - Debug, - HashStable_Generic -)] -pub enum Unsafety { - Unsafe, - Normal, -} - -impl Unsafety { - pub fn prefix_str(&self) -> &'static str { - match self { - Unsafety::Unsafe => "unsafe ", - Unsafety::Normal => "", - } - } -} - -impl fmt::Display for Unsafety { - fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { - fmt::Display::fmt( - match *self { - Unsafety::Normal => "normal", - Unsafety::Unsafe => "unsafe", - }, - f, - ) - } +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable, Debug)] +#[derive(HashStable_Generic)] +pub enum Unsafe { + Yes(Span), + No, } #[derive(Copy, Clone, RustcEncodable, RustcDecodable, Debug)] @@ -2162,9 +2130,9 @@ impl IsAsync { #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable, Debug)] #[derive(HashStable_Generic)] -pub enum Constness { - Const, - NotConst, +pub enum Const { + Yes(Span), + No, } /// Item defaultness. @@ -2527,9 +2495,9 @@ impl Extern { /// included in this struct (e.g., `async unsafe fn` or `const extern "C" fn`). #[derive(Clone, Copy, RustcEncodable, RustcDecodable, Debug)] pub struct FnHeader { - pub unsafety: Unsafety, + pub unsafety: Unsafe, pub asyncness: Spanned<IsAsync>, - pub constness: Spanned<Constness>, + pub constness: Const, pub ext: Extern, } @@ -2537,9 +2505,9 @@ impl FnHeader { /// Does this function header have any qualifiers or is it empty? pub fn has_qualifiers(&self) -> bool { let Self { unsafety, asyncness, constness, ext } = self; - matches!(unsafety, Unsafety::Unsafe) + matches!(unsafety, Unsafe::Yes(_)) || asyncness.node.is_async() - || matches!(constness.node, Constness::Const) + || matches!(constness, Const::Yes(_)) || !matches!(ext, Extern::None) } } @@ -2547,9 +2515,9 @@ impl FnHeader { impl Default for FnHeader { fn default() -> FnHeader { FnHeader { - unsafety: Unsafety::Normal, + unsafety: Unsafe::No, asyncness: dummy_spanned(IsAsync::NotAsync), - constness: dummy_spanned(Constness::NotConst), + constness: Const::No, ext: Extern::None, } } @@ -2606,7 +2574,7 @@ pub enum ItemKind { /// A trait declaration (`trait`). /// /// E.g., `trait Foo { .. }`, `trait Foo<T> { .. }` or `auto trait Foo {}`. - Trait(IsAuto, Unsafety, Generics, GenericBounds, Vec<P<AssocItem>>), + Trait(IsAuto, Unsafe, Generics, GenericBounds, Vec<P<AssocItem>>), /// Trait alias /// /// E.g., `trait Foo = Bar + Quux;`. @@ -2615,10 +2583,10 @@ pub enum ItemKind { /// /// E.g., `impl<A> Foo<A> { .. }` or `impl<A> Trait for Foo<A> { .. }`. Impl { - unsafety: Unsafety, + unsafety: Unsafe, polarity: ImplPolarity, defaultness: Defaultness, - constness: Constness, + constness: Const, generics: Generics, /// The trait being implemented, if any. diff --git a/src/test/ui/coherence/coherence-negative-impls-safe.stderr b/src/test/ui/coherence/coherence-negative-impls-safe.stderr index c47c9d25e36..4db66af6783 100644 --- a/src/test/ui/coherence/coherence-negative-impls-safe.stderr +++ b/src/test/ui/coherence/coherence-negative-impls-safe.stderr @@ -2,7 +2,9 @@ error[E0198]: negative impls cannot be unsafe --> $DIR/coherence-negative-impls-safe.rs:7:1 | LL | unsafe impl !Send for TestType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | unsafe because of this error: aborting due to previous error diff --git a/src/test/ui/const-generics/const-fn-with-const-param.stderr b/src/test/ui/const-generics/const-fn-with-const-param.stderr index 3437ed33d0c..68670963f8e 100644 --- a/src/test/ui/const-generics/const-fn-with-const-param.stderr +++ b/src/test/ui/const-generics/const-fn-with-const-param.stderr @@ -1,7 +1,11 @@ error: const parameters are not permitted in `const fn` --> $DIR/const-fn-with-const-param.rs:4:1 | -LL | / const fn const_u32_identity<const X: u32>() -> u32 { +LL | const fn const_u32_identity<const X: u32>() -> u32 { + | ^---- + | | + | _`const fn` because of this + | | LL | | LL | | X LL | | } diff --git a/src/test/ui/error-codes/E0197.stderr b/src/test/ui/error-codes/E0197.stderr index bb7b6474d3e..51ed9c83bc9 100644 --- a/src/test/ui/error-codes/E0197.stderr +++ b/src/test/ui/error-codes/E0197.stderr @@ -2,7 +2,9 @@ error[E0197]: inherent impls cannot be unsafe --> $DIR/E0197.rs:3:1 | LL | unsafe impl Foo { } - | ^^^^^^^^^^^^^^^^^^^ + | ------^^^^^^^^^^^^^ + | | + | unsafe because of this error: aborting due to previous error diff --git a/src/test/ui/error-codes/E0198.stderr b/src/test/ui/error-codes/E0198.stderr index 0d3706336a9..90e8b4abd12 100644 --- a/src/test/ui/error-codes/E0198.stderr +++ b/src/test/ui/error-codes/E0198.stderr @@ -2,7 +2,9 @@ error[E0198]: negative impls cannot be unsafe --> $DIR/E0198.rs:5:1 | LL | unsafe impl !Send for Foo { } - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------^^^^^^^^^^^^^^^^^^^^^^^ + | | + | unsafe because of this error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr index b196f9ef573..061af3c94b4 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.gated.stderr @@ -2,7 +2,9 @@ error: const trait impls are not yet implemented --> $DIR/feature-gate.rs:9:1 | LL | impl const T for S {} - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^-----^^^^^^^^^^^ + | | + | const because of this error: aborting due to previous error diff --git a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr index 6e1cdde0843..cfe226ea7a7 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/feature-gate.stock.stderr @@ -11,7 +11,9 @@ error: const trait impls are not yet implemented --> $DIR/feature-gate.rs:9:1 | LL | impl const T for S {} - | ^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^-----^^^^^^^^^^^ + | | + | const because of this error: aborting due to 2 previous errors diff --git a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr index 508c6f4c747..bdc95ff2a57 100644 --- a/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr +++ b/src/test/ui/rfc-2632-const-trait-impl/inherent-impl.stderr @@ -2,7 +2,9 @@ error: inherent impls cannot be `const` --> $DIR/inherent-impl.rs:9:1 | LL | impl const S {} - | ^^^^^^^^^^^^^^^ + | ^^^^^-----^^^^^ + | | + | `const` because of this | = note: only trait implementations may be annotated with `const` @@ -10,7 +12,9 @@ error: inherent impls cannot be `const` --> $DIR/inherent-impl.rs:13:1 | LL | impl const T {} - | ^^^^^^^^^^^^^^^ + | ^^^^^-----^^^^^ + | | + | `const` because of this | = note: only trait implementations may be annotated with `const` @@ -18,13 +22,17 @@ error: const trait impls are not yet implemented --> $DIR/inherent-impl.rs:9:1 | LL | impl const S {} - | ^^^^^^^^^^^^^^^ + | ^^^^^-----^^^^^ + | | + | const because of this error: const trait impls are not yet implemented --> $DIR/inherent-impl.rs:13:1 | LL | impl const T {} - | ^^^^^^^^^^^^^^^ + | ^^^^^-----^^^^^ + | | + | const because of this error: aborting due to 4 previous errors diff --git a/src/test/ui/syntax-trait-polarity.stderr b/src/test/ui/syntax-trait-polarity.stderr index b66db9feedb..fef3a650888 100644 --- a/src/test/ui/syntax-trait-polarity.stderr +++ b/src/test/ui/syntax-trait-polarity.stderr @@ -8,7 +8,9 @@ error[E0198]: negative impls cannot be unsafe --> $DIR/syntax-trait-polarity.rs:12:1 | LL | unsafe impl !Send for TestType {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | unsafe because of this error: inherent impls cannot be negative --> $DIR/syntax-trait-polarity.rs:19:1 @@ -20,7 +22,9 @@ error[E0198]: negative impls cannot be unsafe --> $DIR/syntax-trait-polarity.rs:22:1 | LL | unsafe impl<T> !Send for TestType2<T> {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | unsafe because of this error[E0192]: negative impls are only allowed for auto traits (e.g., `Send` and `Sync`) --> $DIR/syntax-trait-polarity.rs:14:1 diff --git a/src/test/ui/traits/trait-safety-inherent-impl.stderr b/src/test/ui/traits/trait-safety-inherent-impl.stderr index 3911261083e..c398785d394 100644 --- a/src/test/ui/traits/trait-safety-inherent-impl.stderr +++ b/src/test/ui/traits/trait-safety-inherent-impl.stderr @@ -1,7 +1,11 @@ error[E0197]: inherent impls cannot be unsafe --> $DIR/trait-safety-inherent-impl.rs:5:1 | -LL | / unsafe impl SomeStruct { +LL | unsafe impl SomeStruct { + | ^----- + | | + | _unsafe because of this + | | LL | | fn foo(self) { } LL | | } | |_^ |
