Auto merge of #66225 - Centril:rollup-it0t5tk, r=Centril

Rollup of 5 pull requests

Successful merges:

 - #65785 (Transition future compat lints to {ERROR, DENY} - Take 2)
 - #66007 (Remove "here" from "expected one of X here")
 - #66043 (rename Memory::get methods to get_raw to indicate their unchecked nature)
 - #66154 (miri: Rename to_{u,i}size to to_machine_{u,i}size)
 - #66188 (`MethodSig` -> `FnSig` & Use it in `ItemKind::Fn`)

Failed merges:

r? @ghost
This commit is contained in:
bors 2019-11-08 15:52:14 +00:00
commit 9e346646e9
224 changed files with 641 additions and 1197 deletions

View File

@ -45,53 +45,6 @@ error: defaults for type parameters are only allowed in `struct`, `enum`, `type`
= note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887> = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
``` ```
## legacy-constructor-visibility
[RFC 1506](https://github.com/rust-lang/rfcs/blob/master/text/1506-adt-kinds.md) modified some
visibility rules, and changed the visibility of struct constructors. Some
example code that triggers this lint:
```rust,ignore
mod m {
pub struct S(u8);
fn f() {
// this is trying to use S from the 'use' line, but because the `u8` is
// not pub, it is private
::S;
}
}
use m::S;
```
This will produce:
```text
error: private struct constructors are not usable through re-exports in outer modules
--> src/main.rs:5:9
|
5 | ::S;
| ^^^
|
= note: `#[deny(legacy_constructor_visibility)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #39207 <https://github.com/rust-lang/rust/issues/39207>
```
## legacy-directory-ownership
The legacy_directory_ownership warning is issued when
* There is a non-inline module with a `#[path]` attribute (e.g. `#[path = "foo.rs"] mod bar;`),
* The module's file ("foo.rs" in the above example) is not named "mod.rs", and
* The module's file contains a non-inline child module without a `#[path]` attribute.
The warning can be fixed by renaming the parent module to "mod.rs" and moving
it into its own directory if appropriate.
## missing-fragment-specifier ## missing-fragment-specifier
The missing_fragment_specifier warning is issued when an unused pattern in a The missing_fragment_specifier warning is issued when an unused pattern in a
@ -169,40 +122,50 @@ error: literal out of range for u8
| |
``` ```
## parenthesized-params-in-types-and-modules ## patterns-in-fns-without-body
This lint detects incorrect parentheses. Some example code that triggers this This lint detects patterns in functions without body were that were
lint: previously erroneously allowed. Some example code that triggers this lint:
```rust,ignore ```rust,compile_fail
let x = 5 as usize(); trait Trait {
fn foo(mut arg: u8);
}
``` ```
This will produce: This will produce:
```text ```text
error: parenthesized parameters may only be used with a trait warning: patterns aren't allowed in methods without bodies
--> src/main.rs:2:21 --> src/main.rs:2:12
| |
2 | let x = 5 as usize(); 2 | fn foo(mut arg: u8);
| ^^ | ^^^^^^^
| |
= note: `#[deny(parenthesized_params_in_types_and_modules)]` on by default = note: `#[warn(patterns_in_fns_without_body)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #42238 <https://github.com/rust-lang/rust/issues/42238> = note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
``` ```
To fix it, remove the `()`s. To fix this, remove the pattern; it can be used in the implementation without
being used in the definition. That is:
```rust
trait Trait {
fn foo(arg: u8);
}
impl Trait for i32 {
fn foo(mut arg: u8) {
}
}
```
## pub-use-of-private-extern-crate ## pub-use-of-private-extern-crate
This lint detects a specific situation of re-exporting a private `extern crate`; This lint detects a specific situation of re-exporting a private `extern crate`;
## safe-extern-statics
In older versions of Rust, there was a soundness issue where `extern static`s were allowed
to be accessed in safe code. This lint now catches and denies this kind of code.
## unknown-crate-types ## unknown-crate-types
This lint detects an unknown crate type found in a `#[crate_type]` directive. Some This lint detects an unknown crate type found in a `#[crate_type]` directive. Some

View File

@ -307,46 +307,6 @@ warning: path statement with no effect
| |
``` ```
## patterns-in-fns-without-body
This lint detects patterns in functions without body were that were
previously erroneously allowed. Some example code that triggers this lint:
```rust
trait Trait {
fn foo(mut arg: u8);
}
```
This will produce:
```text
warning: patterns aren't allowed in methods without bodies
--> src/main.rs:2:12
|
2 | fn foo(mut arg: u8);
| ^^^^^^^
|
= note: `#[warn(patterns_in_fns_without_body)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #35203 <https://github.com/rust-lang/rust/issues/35203>
```
To fix this, remove the pattern; it can be used in the implementation without
being used in the definition. That is:
```rust
trait Trait {
fn foo(arg: u8);
}
impl Trait for i32 {
fn foo(mut arg: u8) {
}
}
```
## plugin-as-library ## plugin-as-library
This lint detects when compiler plugins are used as ordinary library in This lint detects when compiler plugins are used as ordinary library in

View File

@ -45,7 +45,7 @@ pub enum FnKind<'a> {
ItemFn(Ident, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]), ItemFn(Ident, &'a Generics, FnHeader, &'a Visibility, &'a [Attribute]),
/// `fn foo(&self)` /// `fn foo(&self)`
Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a [Attribute]), Method(Ident, &'a FnSig, Option<&'a Visibility>, &'a [Attribute]),
/// `|x, y| {}` /// `|x, y| {}`
Closure(&'a [Attribute]), Closure(&'a [Attribute]),
@ -481,13 +481,13 @@ pub fn walk_item<'v, V: Visitor<'v>>(visitor: &mut V, item: &'v Item) {
visitor.visit_ty(typ); visitor.visit_ty(typ);
visitor.visit_nested_body(body); visitor.visit_nested_body(body);
} }
ItemKind::Fn(ref declaration, header, ref generics, body_id) => { ItemKind::Fn(ref sig, ref generics, body_id) => {
visitor.visit_fn(FnKind::ItemFn(item.ident, visitor.visit_fn(FnKind::ItemFn(item.ident,
generics, generics,
header, sig.header,
&item.vis, &item.vis,
&item.attrs), &item.attrs),
declaration, &sig.decl,
body_id, body_id,
item.span, item.span,
item.hir_id) item.hir_id)

View File

@ -44,8 +44,7 @@ use crate::hir::def::{Namespace, Res, DefKind, PartialRes, PerNS};
use crate::hir::{GenericArg, ConstArg}; use crate::hir::{GenericArg, ConstArg};
use crate::hir::ptr::P; use crate::hir::ptr::P;
use crate::lint; use crate::lint;
use crate::lint::builtin::{self, PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES, use crate::lint::builtin::{self, ELIDED_LIFETIMES_IN_PATHS};
ELIDED_LIFETIMES_IN_PATHS};
use crate::middle::cstore::CrateStore; use crate::middle::cstore::CrateStore;
use crate::session::Session; use crate::session::Session;
use crate::session::config::nightly_options; use crate::session::config::nightly_options;
@ -298,7 +297,6 @@ enum ParamMode {
enum ParenthesizedGenericArgs { enum ParenthesizedGenericArgs {
Ok, Ok,
Warn,
Err, Err,
} }
@ -1701,29 +1699,19 @@ impl<'a> LoweringContext<'a> {
}; };
let parenthesized_generic_args = match partial_res.base_res() { let parenthesized_generic_args = match partial_res.base_res() {
// `a::b::Trait(Args)` // `a::b::Trait(Args)`
Res::Def(DefKind::Trait, _) Res::Def(DefKind::Trait, _) if i + 1 == proj_start => {
if i + 1 == proj_start => ParenthesizedGenericArgs::Ok, ParenthesizedGenericArgs::Ok
}
// `a::b::Trait(Args)::TraitItem` // `a::b::Trait(Args)::TraitItem`
Res::Def(DefKind::Method, _) Res::Def(DefKind::Method, _) |
| Res::Def(DefKind::AssocConst, _) Res::Def(DefKind::AssocConst, _) |
| Res::Def(DefKind::AssocTy, _) Res::Def(DefKind::AssocTy, _) if i + 2 == proj_start => {
if i + 2 == proj_start =>
{
ParenthesizedGenericArgs::Ok ParenthesizedGenericArgs::Ok
} }
// Avoid duplicated errors. // Avoid duplicated errors.
Res::Err => ParenthesizedGenericArgs::Ok, Res::Err => ParenthesizedGenericArgs::Ok,
// An error // An error
Res::Def(DefKind::Struct, _) _ => ParenthesizedGenericArgs::Err,
| Res::Def(DefKind::Enum, _)
| Res::Def(DefKind::Union, _)
| Res::Def(DefKind::TyAlias, _)
| Res::Def(DefKind::Variant, _) if i + 1 == proj_start =>
{
ParenthesizedGenericArgs::Err
}
// A warning for now, for compatibility reasons.
_ => ParenthesizedGenericArgs::Warn,
}; };
let num_lifetimes = type_def_id.map_or(0, |def_id| { let num_lifetimes = type_def_id.map_or(0, |def_id| {
@ -1786,7 +1774,7 @@ impl<'a> LoweringContext<'a> {
segment, segment,
param_mode, param_mode,
0, 0,
ParenthesizedGenericArgs::Warn, ParenthesizedGenericArgs::Err,
itctx.reborrow(), itctx.reborrow(),
None, None,
)); ));
@ -1862,15 +1850,6 @@ impl<'a> LoweringContext<'a> {
} }
GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args { GenericArgs::Parenthesized(ref data) => match parenthesized_generic_args {
ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data), ParenthesizedGenericArgs::Ok => self.lower_parenthesized_parameter_data(data),
ParenthesizedGenericArgs::Warn => {
self.resolver.lint_buffer().buffer_lint(
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
CRATE_NODE_ID,
data.span,
msg.into(),
);
(hir::GenericArgs::none(), true)
}
ParenthesizedGenericArgs::Err => { ParenthesizedGenericArgs::Err => {
let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg); let mut err = struct_span_err!(self.sess, data.span, E0214, "{}", msg);
err.span_label(data.span, "only `Fn` traits may use parentheses"); err.span_label(data.span, "only `Fn` traits may use parentheses");

View File

@ -306,7 +306,7 @@ impl LoweringContext<'_> {
self.lower_const_body(e) self.lower_const_body(e)
) )
} }
ItemKind::Fn(ref decl, header, ref generics, ref body) => { ItemKind::Fn(FnSig { ref decl, header }, ref generics, ref body) => {
let fn_def_id = self.resolver.definitions().local_def_id(id); let fn_def_id = self.resolver.definitions().local_def_id(id);
self.with_new_scopes(|this| { self.with_new_scopes(|this| {
this.current_item = Some(ident.span); this.current_item = Some(ident.span);
@ -317,7 +317,7 @@ impl LoweringContext<'_> {
// declaration (decl), not the return types. // declaration (decl), not the return types.
let body_id = this.lower_maybe_async_body(&decl, header.asyncness.node, body); let body_id = this.lower_maybe_async_body(&decl, header.asyncness.node, body);
let (generics, fn_decl) = this.add_in_band_defs( let (generics, decl) = this.add_in_band_defs(
generics, generics,
fn_def_id, fn_def_id,
AnonymousLifetimeMode::PassThrough, AnonymousLifetimeMode::PassThrough,
@ -328,13 +328,8 @@ impl LoweringContext<'_> {
header.asyncness.node.opt_return_id() header.asyncness.node.opt_return_id()
), ),
); );
let sig = hir::FnSig { decl, header: this.lower_fn_header(header) };
hir::ItemKind::Fn( hir::ItemKind::Fn(sig, generics, body_id)
fn_decl,
this.lower_fn_header(header),
generics,
body_id,
)
}) })
} }
ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)), ItemKind::Mod(ref m) => hir::ItemKind::Mod(self.lower_mod(m)),
@ -1260,11 +1255,11 @@ impl LoweringContext<'_> {
fn lower_method_sig( fn lower_method_sig(
&mut self, &mut self,
generics: &Generics, generics: &Generics,
sig: &MethodSig, sig: &FnSig,
fn_def_id: DefId, fn_def_id: DefId,
impl_trait_return_allow: bool, impl_trait_return_allow: bool,
is_async: Option<NodeId>, is_async: Option<NodeId>,
) -> (hir::Generics, hir::MethodSig) { ) -> (hir::Generics, hir::FnSig) {
let header = self.lower_fn_header(sig.header); let header = self.lower_fn_header(sig.header);
let (generics, decl) = self.add_in_band_defs( let (generics, decl) = self.add_in_band_defs(
generics, generics,
@ -1277,7 +1272,7 @@ impl LoweringContext<'_> {
is_async, is_async,
), ),
); );
(generics, hir::MethodSig { header, decl }) (generics, hir::FnSig { header, decl })
} }
fn lower_is_auto(&mut self, a: IsAuto) -> hir::IsAuto { fn lower_is_auto(&mut self, a: IsAuto) -> hir::IsAuto {

View File

@ -158,25 +158,25 @@ impl<'a> FnLikeNode<'a> {
pub fn body(self) -> ast::BodyId { pub fn body(self) -> ast::BodyId {
self.handle(|i: ItemFnParts<'a>| i.body, self.handle(|i: ItemFnParts<'a>| i.body,
|_, _, _: &'a ast::MethodSig, _, body: ast::BodyId, _, _| body, |_, _, _: &'a ast::FnSig, _, body: ast::BodyId, _, _| body,
|c: ClosureParts<'a>| c.body) |c: ClosureParts<'a>| c.body)
} }
pub fn decl(self) -> &'a FnDecl { pub fn decl(self) -> &'a FnDecl {
self.handle(|i: ItemFnParts<'a>| &*i.decl, self.handle(|i: ItemFnParts<'a>| &*i.decl,
|_, _, sig: &'a ast::MethodSig, _, _, _, _| &sig.decl, |_, _, sig: &'a ast::FnSig, _, _, _, _| &sig.decl,
|c: ClosureParts<'a>| c.decl) |c: ClosureParts<'a>| c.decl)
} }
pub fn span(self) -> Span { pub fn span(self) -> Span {
self.handle(|i: ItemFnParts<'_>| i.span, self.handle(|i: ItemFnParts<'_>| i.span,
|_, _, _: &'a ast::MethodSig, _, _, span, _| span, |_, _, _: &'a ast::FnSig, _, _, span, _| span,
|c: ClosureParts<'_>| c.span) |c: ClosureParts<'_>| c.span)
} }
pub fn id(self) -> ast::HirId { pub fn id(self) -> ast::HirId {
self.handle(|i: ItemFnParts<'_>| i.id, self.handle(|i: ItemFnParts<'_>| i.id,
|id, _, _: &'a ast::MethodSig, _, _, _, _| id, |id, _, _: &'a ast::FnSig, _, _, _, _| id,
|c: ClosureParts<'_>| c.id) |c: ClosureParts<'_>| c.id)
} }
@ -199,7 +199,7 @@ impl<'a> FnLikeNode<'a> {
let closure = |c: ClosureParts<'a>| { let closure = |c: ClosureParts<'a>| {
FnKind::Closure(c.attrs) FnKind::Closure(c.attrs)
}; };
let method = |_, ident: Ident, sig: &'a ast::MethodSig, vis, _, _, attrs| { let method = |_, ident: Ident, sig: &'a ast::FnSig, vis, _, _, attrs| {
FnKind::Method(ident, sig, vis, attrs) FnKind::Method(ident, sig, vis, attrs)
}; };
self.handle(item, method, closure) self.handle(item, method, closure)
@ -209,7 +209,7 @@ impl<'a> FnLikeNode<'a> {
I: FnOnce(ItemFnParts<'a>) -> A, I: FnOnce(ItemFnParts<'a>) -> A,
M: FnOnce(ast::HirId, M: FnOnce(ast::HirId,
Ident, Ident,
&'a ast::MethodSig, &'a ast::FnSig,
Option<&'a ast::Visibility>, Option<&'a ast::Visibility>,
ast::BodyId, ast::BodyId,
Span, Span,
@ -219,16 +219,16 @@ impl<'a> FnLikeNode<'a> {
{ {
match self.node { match self.node {
map::Node::Item(i) => match i.kind { map::Node::Item(i) => match i.kind {
ast::ItemKind::Fn(ref decl, header, ref generics, block) => ast::ItemKind::Fn(ref sig, ref generics, block) =>
item_fn(ItemFnParts { item_fn(ItemFnParts {
id: i.hir_id, id: i.hir_id,
ident: i.ident, ident: i.ident,
decl: &decl, decl: &sig.decl,
body: block, body: block,
vis: &i.vis, vis: &i.vis,
span: i.span, span: i.span,
attrs: &i.attrs, attrs: &i.attrs,
header, header: sig.header,
generics, generics,
}), }),
_ => bug!("item FnLikeNode that is not fn-like"), _ => bug!("item FnLikeNode that is not fn-like"),

View File

@ -100,7 +100,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
// Pick the def data. This need not be unique, but the more // Pick the def data. This need not be unique, but the more
// information we encapsulate into, the better // information we encapsulate into, the better
let def_data = match i.kind { let def_data = match &i.kind {
ItemKind::Impl(..) => DefPathData::Impl, ItemKind::Impl(..) => DefPathData::Impl,
ItemKind::Mod(..) if i.ident.name == kw::Invalid => { ItemKind::Mod(..) if i.ident.name == kw::Invalid => {
return visit::walk_item(self, i); return visit::walk_item(self, i);
@ -109,19 +109,14 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) | ItemKind::Enum(..) | ItemKind::Struct(..) | ItemKind::Union(..) |
ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) | ItemKind::OpaqueTy(..) | ItemKind::ExternCrate(..) | ItemKind::ForeignMod(..) |
ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name), ItemKind::TyAlias(..) => DefPathData::TypeNs(i.ident.name),
ItemKind::Fn( ItemKind::Fn(sig, generics, body) if sig.header.asyncness.node.is_async() => {
ref decl,
ref header,
ref generics,
ref body,
) if header.asyncness.node.is_async() => {
return self.visit_async_fn( return self.visit_async_fn(
i.id, i.id,
i.ident.name, i.ident.name,
i.span, i.span,
header, &sig.header,
generics, generics,
decl, &sig.decl,
body, body,
) )
} }
@ -228,7 +223,7 @@ impl<'a> visit::Visitor<'a> for DefCollector<'a> {
fn visit_impl_item(&mut self, ii: &'a ImplItem) { fn visit_impl_item(&mut self, ii: &'a ImplItem) {
let def_data = match ii.kind { let def_data = match ii.kind {
ImplItemKind::Method(MethodSig { ImplItemKind::Method(FnSig {
ref header, ref header,
ref decl, ref decl,
}, ref body) if header.asyncness.node.is_async() => { }, ref body) if header.asyncness.node.is_async() => {

View File

@ -49,21 +49,21 @@ impl<'hir> Entry<'hir> {
match self.node { match self.node {
Node::Item(ref item) => { Node::Item(ref item) => {
match item.kind { match item.kind {
ItemKind::Fn(ref fn_decl, _, _, _) => Some(fn_decl), ItemKind::Fn(ref sig, _, _) => Some(&sig.decl),
_ => None, _ => None,
} }
} }
Node::TraitItem(ref item) => { Node::TraitItem(ref item) => {
match item.kind { match item.kind {
TraitItemKind::Method(ref method_sig, _) => Some(&method_sig.decl), TraitItemKind::Method(ref sig, _) => Some(&sig.decl),
_ => None _ => None
} }
} }
Node::ImplItem(ref item) => { Node::ImplItem(ref item) => {
match item.kind { match item.kind {
ImplItemKind::Method(ref method_sig, _) => Some(&method_sig.decl), ImplItemKind::Method(ref sig, _) => Some(&sig.decl),
_ => None, _ => None,
} }
} }
@ -85,7 +85,7 @@ impl<'hir> Entry<'hir> {
match item.kind { match item.kind {
ItemKind::Const(_, body) | ItemKind::Const(_, body) |
ItemKind::Static(.., body) | ItemKind::Static(.., body) |
ItemKind::Fn(_, _, _, body) => Some(body), ItemKind::Fn(.., body) => Some(body),
_ => None, _ => None,
} }
} }
@ -605,7 +605,7 @@ impl<'hir> Map<'hir> {
Node::TraitItem(ref trait_item) => Some(&trait_item.generics), Node::TraitItem(ref trait_item) => Some(&trait_item.generics),
Node::Item(ref item) => { Node::Item(ref item) => {
match item.kind { match item.kind {
ItemKind::Fn(_, _, ref generics, _) | ItemKind::Fn(_, ref generics, _) |
ItemKind::TyAlias(_, ref generics) | ItemKind::TyAlias(_, ref generics) |
ItemKind::Enum(_, ref generics) | ItemKind::Enum(_, ref generics) |
ItemKind::Struct(_, ref generics) | ItemKind::Struct(_, ref generics) |
@ -702,9 +702,9 @@ impl<'hir> Map<'hir> {
.. ..
}) => true, }) => true,
Node::Item(&Item { Node::Item(&Item {
kind: ItemKind::Fn(_, header, ..), kind: ItemKind::Fn(ref sig, ..),
.. ..
}) => header.constness == Constness::Const, }) => sig.header.constness == Constness::Const,
_ => false, _ => false,
} }
} }

View File

@ -1876,9 +1876,10 @@ pub struct MutTy {
pub mutbl: Mutability, pub mutbl: Mutability,
} }
/// Represents a method's signature in a trait declaration or implementation. /// Represents a function's signature in a trait declaration,
/// trait implementation, or a free function.
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable)] #[derive(RustcEncodable, RustcDecodable, Debug, HashStable)]
pub struct MethodSig { pub struct FnSig {
pub header: FnHeader, pub header: FnHeader,
pub decl: P<FnDecl>, pub decl: P<FnDecl>,
} }
@ -1921,7 +1922,7 @@ pub enum TraitItemKind {
/// An associated constant with an optional value (otherwise `impl`s must contain a value). /// An associated constant with an optional value (otherwise `impl`s must contain a value).
Const(P<Ty>, Option<BodyId>), Const(P<Ty>, Option<BodyId>),
/// A method with an optional body. /// A method with an optional body.
Method(MethodSig, TraitMethod), Method(FnSig, TraitMethod),
/// An associated type with (possibly empty) bounds and optional concrete /// An associated type with (possibly empty) bounds and optional concrete
/// type. /// type.
Type(GenericBounds, Option<P<Ty>>), Type(GenericBounds, Option<P<Ty>>),
@ -1955,7 +1956,7 @@ pub enum ImplItemKind {
/// of the expression. /// of the expression.
Const(P<Ty>, BodyId), Const(P<Ty>, BodyId),
/// A method implementation with the given signature and body. /// A method implementation with the given signature and body.
Method(MethodSig, BodyId), Method(FnSig, BodyId),
/// An associated type. /// An associated type.
TyAlias(P<Ty>), TyAlias(P<Ty>),
/// An associated `type = impl Trait`. /// An associated `type = impl Trait`.
@ -2534,7 +2535,7 @@ pub enum ItemKind {
/// A `const` item. /// A `const` item.
Const(P<Ty>, BodyId), Const(P<Ty>, BodyId),
/// A function declaration. /// A function declaration.
Fn(P<FnDecl>, FnHeader, Generics, BodyId), Fn(FnSig, Generics, BodyId),
/// A module. /// A module.
Mod(Mod), Mod(Mod),
/// An external module, e.g. `extern { .. }`. /// An external module, e.g. `extern { .. }`.
@ -2599,7 +2600,7 @@ impl ItemKind {
pub fn generics(&self) -> Option<&Generics> { pub fn generics(&self) -> Option<&Generics> {
Some(match *self { Some(match *self {
ItemKind::Fn(_, _, ref generics, _) | ItemKind::Fn(_, ref generics, _) |
ItemKind::TyAlias(_, ref generics) | ItemKind::TyAlias(_, ref generics) |
ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) | ItemKind::OpaqueTy(OpaqueTy { ref generics, impl_trait_fn: None, .. }) |
ItemKind::Enum(_, ref generics) | ItemKind::Enum(_, ref generics) |

View File

@ -533,10 +533,10 @@ impl<'a> State<'a> {
self.s.word(";"); self.s.word(";");
self.end(); // end the outer cbox self.end(); // end the outer cbox
} }
hir::ItemKind::Fn(ref decl, header, ref param_names, body) => { hir::ItemKind::Fn(ref sig, ref param_names, body) => {
self.head(""); self.head("");
self.print_fn(decl, self.print_fn(&sig.decl,
header, sig.header,
Some(item.ident.name), Some(item.ident.name),
param_names, param_names,
&item.vis, &item.vis,
@ -835,7 +835,7 @@ impl<'a> State<'a> {
} }
pub fn print_method_sig(&mut self, pub fn print_method_sig(&mut self,
ident: ast::Ident, ident: ast::Ident,
m: &hir::MethodSig, m: &hir::FnSig,
generics: &hir::Generics, generics: &hir::Generics,
vis: &hir::Visibility, vis: &hir::Visibility,
arg_names: &[ast::Ident], arg_names: &[ast::Ident],

View File

@ -31,10 +31,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
if let Some(hir_id) = self.tcx().hir().as_local_hir_id(def_id) { if let Some(hir_id) = self.tcx().hir().as_local_hir_id(def_id) {
let fndecl = match self.tcx().hir().get(hir_id) { let fndecl = match self.tcx().hir().get(hir_id) {
Node::Item(&hir::Item { Node::Item(&hir::Item {
kind: hir::ItemKind::Fn(ref fndecl, ..), kind: hir::ItemKind::Fn(ref m, ..),
.. ..
}) => &fndecl, })
Node::TraitItem(&hir::TraitItem { | Node::TraitItem(&hir::TraitItem {
kind: hir::TraitItemKind::Method(ref m, ..), kind: hir::TraitItemKind::Method(ref m, ..),
.. ..
}) })

View File

@ -177,16 +177,6 @@ declare_lint! {
"lints that have been renamed or removed" "lints that have been renamed or removed"
} }
declare_lint! {
pub SAFE_EXTERN_STATICS,
Deny,
"safe access to extern statics was erroneously allowed",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #36247 <https://github.com/rust-lang/rust/issues/36247>",
edition: None,
};
}
declare_lint! { declare_lint! {
pub SAFE_PACKED_BORROWS, pub SAFE_PACKED_BORROWS,
Warn, Warn,
@ -199,7 +189,7 @@ declare_lint! {
declare_lint! { declare_lint! {
pub PATTERNS_IN_FNS_WITHOUT_BODY, pub PATTERNS_IN_FNS_WITHOUT_BODY,
Warn, Deny,
"patterns in functions without body were erroneously allowed", "patterns in functions without body were erroneously allowed",
@future_incompatible = FutureIncompatibleInfo { @future_incompatible = FutureIncompatibleInfo {
reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>", reference: "issue #35203 <https://github.com/rust-lang/rust/issues/35203>",
@ -207,27 +197,6 @@ declare_lint! {
}; };
} }
declare_lint! {
pub LEGACY_DIRECTORY_OWNERSHIP,
Deny,
"non-inline, non-`#[path]` modules (e.g., `mod foo;`) were erroneously allowed in some files \
not named `mod.rs`",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #37872 <https://github.com/rust-lang/rust/issues/37872>",
edition: None,
};
}
declare_lint! {
pub LEGACY_CONSTRUCTOR_VISIBILITY,
Deny,
"detects use of struct constructors that would be invisible with new visibility rules",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #39207 <https://github.com/rust-lang/rust/issues/39207>",
edition: None,
};
}
declare_lint! { declare_lint! {
pub MISSING_FRAGMENT_SPECIFIER, pub MISSING_FRAGMENT_SPECIFIER,
Deny, Deny,
@ -238,16 +207,6 @@ declare_lint! {
}; };
} }
declare_lint! {
pub PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
Deny,
"detects parenthesized generic parameters in type and module names",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #42238 <https://github.com/rust-lang/rust/issues/42238>",
edition: None,
};
}
declare_lint! { declare_lint! {
pub LATE_BOUND_LIFETIME_ARGUMENTS, pub LATE_BOUND_LIFETIME_ARGUMENTS,
Warn, Warn,
@ -372,16 +331,6 @@ declare_lint! {
"detects labels that are never used" "detects labels that are never used"
} }
declare_lint! {
pub DUPLICATE_MACRO_EXPORTS,
Deny,
"detects duplicate macro exports",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #35896 <https://github.com/rust-lang/rust/issues/35896>",
edition: Some(Edition::Edition2018),
};
}
declare_lint! { declare_lint! {
pub INTRA_DOC_LINK_RESOLUTION_FAILURE, pub INTRA_DOC_LINK_RESOLUTION_FAILURE,
Warn, Warn,
@ -459,7 +408,7 @@ declare_lint! {
pub mod parser { pub mod parser {
declare_lint! { declare_lint! {
pub ILL_FORMED_ATTRIBUTE_INPUT, pub ILL_FORMED_ATTRIBUTE_INPUT,
Warn, Deny,
"ill-formed attribute inputs that were previously accepted and used in practice", "ill-formed attribute inputs that were previously accepted and used in practice",
@future_incompatible = super::FutureIncompatibleInfo { @future_incompatible = super::FutureIncompatibleInfo {
reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>", reference: "issue #57571 <https://github.com/rust-lang/rust/issues/57571>",
@ -497,16 +446,6 @@ declare_lint! {
}; };
} }
declare_lint! {
pub NESTED_IMPL_TRAIT,
Warn,
"nested occurrence of `impl Trait` type",
@future_incompatible = FutureIncompatibleInfo {
reference: "issue #59014 <https://github.com/rust-lang/rust/issues/59014>",
edition: None,
};
}
declare_lint! { declare_lint! {
pub MUTABLE_BORROW_RESERVATION_CONFLICT, pub MUTABLE_BORROW_RESERVATION_CONFLICT,
Warn, Warn,
@ -556,13 +495,9 @@ declare_lint_pass! {
INVALID_TYPE_PARAM_DEFAULT, INVALID_TYPE_PARAM_DEFAULT,
CONST_ERR, CONST_ERR,
RENAMED_AND_REMOVED_LINTS, RENAMED_AND_REMOVED_LINTS,
SAFE_EXTERN_STATICS,
SAFE_PACKED_BORROWS, SAFE_PACKED_BORROWS,
PATTERNS_IN_FNS_WITHOUT_BODY, PATTERNS_IN_FNS_WITHOUT_BODY,
LEGACY_DIRECTORY_OWNERSHIP,
LEGACY_CONSTRUCTOR_VISIBILITY,
MISSING_FRAGMENT_SPECIFIER, MISSING_FRAGMENT_SPECIFIER,
PARENTHESIZED_PARAMS_IN_TYPES_AND_MODULES,
LATE_BOUND_LIFETIME_ARGUMENTS, LATE_BOUND_LIFETIME_ARGUMENTS,
ORDER_DEPENDENT_TRAIT_OBJECTS, ORDER_DEPENDENT_TRAIT_OBJECTS,
DEPRECATED, DEPRECATED,
@ -578,7 +513,6 @@ declare_lint_pass! {
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE,
UNSTABLE_NAME_COLLISIONS, UNSTABLE_NAME_COLLISIONS,
IRREFUTABLE_LET_PATTERNS, IRREFUTABLE_LET_PATTERNS,
DUPLICATE_MACRO_EXPORTS,
INTRA_DOC_LINK_RESOLUTION_FAILURE, INTRA_DOC_LINK_RESOLUTION_FAILURE,
MISSING_DOC_CODE_EXAMPLES, MISSING_DOC_CODE_EXAMPLES,
PRIVATE_DOC_TESTS, PRIVATE_DOC_TESTS,
@ -590,7 +524,6 @@ declare_lint_pass! {
parser::META_VARIABLE_MISUSE, parser::META_VARIABLE_MISUSE,
DEPRECATED_IN_FUTURE, DEPRECATED_IN_FUTURE,
AMBIGUOUS_ASSOCIATED_ITEMS, AMBIGUOUS_ASSOCIATED_ITEMS,
NESTED_IMPL_TRAIT,
MUTABLE_BORROW_RESERVATION_CONFLICT, MUTABLE_BORROW_RESERVATION_CONFLICT,
INDIRECT_STRUCTURAL_MATCH, INDIRECT_STRUCTURAL_MATCH,
SOFT_UNSTABLE, SOFT_UNSTABLE,
@ -604,13 +537,11 @@ pub enum BuiltinLintDiagnostics {
Normal, Normal,
BareTraitObject(Span, /* is_global */ bool), BareTraitObject(Span, /* is_global */ bool),
AbsPathWithModule(Span), AbsPathWithModule(Span),
DuplicatedMacroExports(ast::Ident, Span, Span),
ProcMacroDeriveResolutionFallback(Span), ProcMacroDeriveResolutionFallback(Span),
MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), MacroExpandedMacroExportsAccessedByAbsolutePaths(Span),
ElidedLifetimesInPaths(usize, Span, bool, Span, String), ElidedLifetimesInPaths(usize, Span, bool, Span, String),
UnknownCrateTypes(Span, String, String), UnknownCrateTypes(Span, String, String),
UnusedImports(String, Vec<(Span, String)>), UnusedImports(String, Vec<(Span, String)>),
NestedImplTrait { outer_impl_trait_span: Span, inner_impl_trait_span: Span },
RedundantImport(Vec<(Span, bool)>, ast::Ident), RedundantImport(Vec<(Span, bool)>, ast::Ident),
DeprecatedMacro(Option<Symbol>, Span), DeprecatedMacro(Option<Symbol>, Span),
} }
@ -687,10 +618,6 @@ impl BuiltinLintDiagnostics {
}; };
db.span_suggestion(span, "use `crate`", sugg, app); db.span_suggestion(span, "use `crate`", sugg, app);
} }
BuiltinLintDiagnostics::DuplicatedMacroExports(ident, earlier_span, later_span) => {
db.span_label(later_span, format!("`{}` already exported", ident));
db.span_note(earlier_span, "previous macro export is now shadowed");
}
BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => { BuiltinLintDiagnostics::ProcMacroDeriveResolutionFallback(span) => {
db.span_label(span, "names from parent modules are not \ db.span_label(span, "names from parent modules are not \
accessible without an explicit import"); accessible without an explicit import");
@ -723,12 +650,6 @@ impl BuiltinLintDiagnostics {
); );
} }
} }
BuiltinLintDiagnostics::NestedImplTrait {
outer_impl_trait_span, inner_impl_trait_span
} => {
db.span_label(outer_impl_trait_span, "outer `impl Trait`");
db.span_label(inner_impl_trait_span, "nested `impl Trait` here");
}
BuiltinLintDiagnostics::RedundantImport(spans, ident) => { BuiltinLintDiagnostics::RedundantImport(spans, ident) => {
for (span, is_imported) in spans { for (span, is_imported) in spans {
let introduced = if is_imported { "imported" } else { "defined" }; let introduced = if is_imported { "imported" } else { "defined" };

View File

@ -33,7 +33,7 @@ fn item_might_be_inlined(tcx: TyCtxt<'tcx>, item: &hir::Item, attrs: CodegenFnAt
} }
match item.kind { match item.kind {
hir::ItemKind::Fn(_, header, ..) if header.is_const() => { hir::ItemKind::Fn(ref sig, ..) if sig.header.is_const() => {
return true; return true;
} }
hir::ItemKind::Impl(..) | hir::ItemKind::Impl(..) |
@ -225,8 +225,8 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> {
// If we are building an executable, only explicitly extern // If we are building an executable, only explicitly extern
// types need to be exported. // types need to be exported.
if let Node::Item(item) = *node { if let Node::Item(item) = *node {
let reachable = if let hir::ItemKind::Fn(_, header, ..) = item.kind { let reachable = if let hir::ItemKind::Fn(ref sig, ..) = item.kind {
header.abi != Abi::Rust sig.header.abi != Abi::Rust
} else { } else {
false false
}; };

View File

@ -460,8 +460,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_item(&mut self, item: &'tcx hir::Item) { fn visit_item(&mut self, item: &'tcx hir::Item) {
match item.kind { match item.kind {
hir::ItemKind::Fn(ref decl, _, ref generics, _) => { hir::ItemKind::Fn(ref sig, ref generics, _) => {
self.visit_early_late(None, decl, generics, |this| { self.visit_early_late(None, &sig.decl, generics, |this| {
intravisit::walk_item(this, item); intravisit::walk_item(this, item);
}); });
} }
@ -1524,8 +1524,8 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> {
{ {
match parent { match parent {
Node::Item(item) => { Node::Item(item) => {
if let hir::ItemKind::Fn(decl, _, _, _) = &item.kind { if let hir::ItemKind::Fn(sig, _, _) = &item.kind {
find_arg_use_span(&decl.inputs); find_arg_use_span(&sig.decl.inputs);
} }
}, },
Node::ImplItem(impl_item) => { Node::ImplItem(impl_item) => {

View File

@ -439,7 +439,7 @@ impl<'tcx, Tag> Scalar<Tag> {
Ok(b as u64) Ok(b as u64)
} }
pub fn to_usize(self, cx: &impl HasDataLayout) -> InterpResult<'static, u64> { pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'static, u64> {
let b = self.to_bits(cx.data_layout().pointer_size)?; let b = self.to_bits(cx.data_layout().pointer_size)?;
Ok(b as u64) Ok(b as u64)
} }
@ -465,7 +465,7 @@ impl<'tcx, Tag> Scalar<Tag> {
Ok(b as i64) Ok(b as i64)
} }
pub fn to_isize(self, cx: &impl HasDataLayout) -> InterpResult<'static, i64> { pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'static, i64> {
let sz = cx.data_layout().pointer_size; let sz = cx.data_layout().pointer_size;
let b = self.to_bits(sz)?; let b = self.to_bits(sz)?;
let b = sign_extend(b, sz) as i128; let b = sign_extend(b, sz) as i128;
@ -592,8 +592,8 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
} }
#[inline(always)] #[inline(always)]
pub fn to_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> { pub fn to_machine_usize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, u64> {
self.not_undef()?.to_usize(cx) self.not_undef()?.to_machine_usize(cx)
} }
#[inline(always)] #[inline(always)]
@ -612,8 +612,8 @@ impl<'tcx, Tag> ScalarMaybeUndef<Tag> {
} }
#[inline(always)] #[inline(always)]
pub fn to_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> { pub fn to_machine_isize(self, cx: &impl HasDataLayout) -> InterpResult<'tcx, i64> {
self.not_undef()?.to_isize(cx) self.not_undef()?.to_machine_isize(cx)
} }
} }

View File

@ -2701,7 +2701,6 @@ pub enum UnsafetyViolationKind {
General, General,
/// Permitted both in `const fn`s and regular `fn`s. /// Permitted both in `const fn`s and regular `fn`s.
GeneralAndConstFn, GeneralAndConstFn,
ExternStatic(hir::HirId),
BorrowPacked(hir::HirId), BorrowPacked(hir::HirId),
} }

View File

@ -383,9 +383,9 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let hir = &self.tcx.hir(); let hir = &self.tcx.hir();
let node = hir.find(hir_id)?; let node = hir.find(hir_id)?;
if let hir::Node::Item( if let hir::Node::Item(
hir::Item{kind: hir::ItemKind::Fn(_ ,fn_header ,_ , body_id), .. }) = &node { hir::Item{kind: hir::ItemKind::Fn(sig, _, body_id), .. }) = &node {
self.describe_generator(*body_id).or_else(|| self.describe_generator(*body_id).or_else(||
Some(if let hir::FnHeader{ asyncness: hir::IsAsync::Async, .. } = fn_header { Some(if let hir::FnHeader{ asyncness: hir::IsAsync::Async, .. } = sig.header {
"an async function" "an async function"
} else { } else {
"a function" "a function"
@ -1081,7 +1081,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} }
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(_, _, generics, _), .. kind: hir::ItemKind::Fn(_, generics, _), ..
}) | }) |
hir::Node::TraitItem(hir::TraitItem { hir::Node::TraitItem(hir::TraitItem {
generics, generics,
@ -1112,7 +1112,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
kind: hir::ItemKind::Impl(_, _, _, generics, ..), span, .. kind: hir::ItemKind::Impl(_, _, _, generics, ..), span, ..
}) | }) |
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(_, _, generics, _), span, .. kind: hir::ItemKind::Fn(_, generics, _), span, ..
}) | }) |
hir::Node::Item(hir::Item { hir::Node::Item(hir::Item {
kind: hir::ItemKind::TyAlias(_, generics), span, .. kind: hir::ItemKind::TyAlias(_, generics), span, ..
@ -1436,12 +1436,12 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
let parent_node = hir.get_parent_node(obligation.cause.body_id); let parent_node = hir.get_parent_node(obligation.cause.body_id);
let node = hir.find(parent_node); let node = hir.find(parent_node);
if let Some(hir::Node::Item(hir::Item { if let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(decl, _, _, body_id), kind: hir::ItemKind::Fn(sig, _, body_id),
.. ..
})) = node { })) = node {
let body = hir.body(*body_id); let body = hir.body(*body_id);
if let hir::ExprKind::Block(blk, _) = &body.value.kind { if let hir::ExprKind::Block(blk, _) = &body.value.kind {
if decl.output.span().overlaps(span) && blk.expr.is_none() && if sig.decl.output.span().overlaps(span) && blk.expr.is_none() &&
"()" == &trait_ref.self_ty().to_string() "()" == &trait_ref.self_ty().to_string()
{ {
// FIXME(estebank): When encountering a method with a trait // FIXME(estebank): When encountering a method with a trait
@ -1493,20 +1493,20 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
} }
Node::Item(&hir::Item { Node::Item(&hir::Item {
span, span,
kind: hir::ItemKind::Fn(ref decl, ..), kind: hir::ItemKind::Fn(ref sig, ..),
.. ..
}) | }) |
Node::ImplItem(&hir::ImplItem { Node::ImplItem(&hir::ImplItem {
span, span,
kind: hir::ImplItemKind::Method(hir::MethodSig { ref decl, .. }, _), kind: hir::ImplItemKind::Method(ref sig, _),
.. ..
}) | }) |
Node::TraitItem(&hir::TraitItem { Node::TraitItem(&hir::TraitItem {
span, span,
kind: hir::TraitItemKind::Method(hir::MethodSig { ref decl, .. }, _), kind: hir::TraitItemKind::Method(ref sig, _),
.. ..
}) => { }) => {
(self.tcx.sess.source_map().def_span(span), decl.inputs.iter() (self.tcx.sess.source_map().def_span(span), sig.decl.inputs.iter()
.map(|arg| match arg.clone().kind { .map(|arg| match arg.clone().kind {
hir::TyKind::Tup(ref tys) => ArgKind::Tuple( hir::TyKind::Tup(ref tys) => ArgKind::Tuple(
Some(arg.span), Some(arg.span),
@ -2040,11 +2040,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
.and_then(|parent_did| self.tcx.hir().get_if_local(parent_did)); .and_then(|parent_did| self.tcx.hir().get_if_local(parent_did));
debug!("note_obligation_cause_for_async_await: parent_node={:?}", parent_node); debug!("note_obligation_cause_for_async_await: parent_node={:?}", parent_node);
if let Some(hir::Node::Item(hir::Item { if let Some(hir::Node::Item(hir::Item {
kind: hir::ItemKind::Fn(_, header, _, _), kind: hir::ItemKind::Fn(sig, _, _),
.. ..
})) = parent_node { })) = parent_node {
debug!("note_obligation_cause_for_async_await: header={:?}", header); debug!("note_obligation_cause_for_async_await: header={:?}", sig.header);
if header.asyncness != hir::IsAsync::Async { if sig.header.asyncness != hir::IsAsync::Async {
return false; return false;
} }
} }

View File

@ -786,14 +786,17 @@ impl<'a> ReplaceBodyWithLoop<'a> {
false false
} }
} }
fn is_sig_const(sig: &ast::FnSig) -> bool {
sig.header.constness.node == ast::Constness::Const || Self::should_ignore_fn(&sig.decl)
}
} }
impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> { impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
fn visit_item_kind(&mut self, i: &mut ast::ItemKind) { fn visit_item_kind(&mut self, i: &mut ast::ItemKind) {
let is_const = match i { let is_const = match i {
ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true, ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true,
ast::ItemKind::Fn(ref decl, ref header, _, _) => ast::ItemKind::Fn(ref sig, _, _) => Self::is_sig_const(sig),
header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
_ => false, _ => false,
}; };
self.run(is_const, |s| noop_visit_item_kind(i, s)) self.run(is_const, |s| noop_visit_item_kind(i, s))
@ -802,8 +805,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
fn flat_map_trait_item(&mut self, i: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> { fn flat_map_trait_item(&mut self, i: ast::TraitItem) -> SmallVec<[ast::TraitItem; 1]> {
let is_const = match i.kind { let is_const = match i.kind {
ast::TraitItemKind::Const(..) => true, ast::TraitItemKind::Const(..) => true,
ast::TraitItemKind::Method(ast::MethodSig { ref decl, ref header, .. }, _) => ast::TraitItemKind::Method(ref sig, _) => Self::is_sig_const(sig),
header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
_ => false, _ => false,
}; };
self.run(is_const, |s| noop_flat_map_trait_item(i, s)) self.run(is_const, |s| noop_flat_map_trait_item(i, s))
@ -812,8 +814,7 @@ impl<'a> MutVisitor for ReplaceBodyWithLoop<'a> {
fn flat_map_impl_item(&mut self, i: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> { fn flat_map_impl_item(&mut self, i: ast::ImplItem) -> SmallVec<[ast::ImplItem; 1]> {
let is_const = match i.kind { let is_const = match i.kind {
ast::ImplItemKind::Const(..) => true, ast::ImplItemKind::Const(..) => true,
ast::ImplItemKind::Method(ast::MethodSig { ref decl, ref header, .. }, _) => ast::ImplItemKind::Method(ref sig, _) => Self::is_sig_const(sig),
header.constness.node == ast::Constness::Const || Self::should_ignore_fn(decl),
_ => false, _ => false,
}; };
self.run(is_const, |s| noop_flat_map_impl_item(i, s)) self.run(is_const, |s| noop_flat_map_impl_item(i, s))

View File

@ -339,6 +339,18 @@ fn register_builtins(store: &mut lint::LintStore, no_interleave_lints: bool) {
"converted into hard error, see https://github.com/rust-lang/rust/issues/57742"); "converted into hard error, see https://github.com/rust-lang/rust/issues/57742");
store.register_removed("incoherent_fundamental_impls", store.register_removed("incoherent_fundamental_impls",
"converted into hard error, see https://github.com/rust-lang/rust/issues/46205"); "converted into hard error, see https://github.com/rust-lang/rust/issues/46205");
store.register_removed("legacy_constructor_visibility",
"converted into hard error, see https://github.com/rust-lang/rust/issues/39207");
store.register_removed("legacy_disrectory_ownership",
"converted into hard error, see https://github.com/rust-lang/rust/issues/37872");
store.register_removed("safe_extern_statics",
"converted into hard error, see https://github.com/rust-lang/rust/issues/36247");
store.register_removed("parenthesized_params_in_types_and_modules",
"converted into hard error, see https://github.com/rust-lang/rust/issues/42238");
store.register_removed("duplicate_macro_exports",
"converted into hard error, see https://github.com/rust-lang/rust/issues/35896");
store.register_removed("nested_impl_trait",
"converted into hard error, see https://github.com/rust-lang/rust/issues/59014");
} }
fn register_internals(store: &mut lint::LintStore) { fn register_internals(store: &mut lint::LintStore) {

View File

@ -1095,10 +1095,10 @@ impl EncodeContext<'tcx> {
self.encode_rendered_const_for_body(body_id) self.encode_rendered_const_for_body(body_id)
) )
} }
hir::ItemKind::Fn(_, header, .., body) => { hir::ItemKind::Fn(ref sig, .., body) => {
let data = FnData { let data = FnData {
asyncness: header.asyncness, asyncness: sig.header.asyncness,
constness: header.constness, constness: sig.header.constness,
param_names: self.encode_fn_param_names_for_body(body), param_names: self.encode_fn_param_names_for_body(body),
}; };
@ -1284,14 +1284,14 @@ impl EncodeContext<'tcx> {
let mir = match item.kind { let mir = match item.kind {
hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true, hir::ItemKind::Static(..) | hir::ItemKind::Const(..) => true,
hir::ItemKind::Fn(_, header, ..) => { hir::ItemKind::Fn(ref sig, ..) => {
let generics = tcx.generics_of(def_id); let generics = tcx.generics_of(def_id);
let needs_inline = let needs_inline =
(generics.requires_monomorphization(tcx) || (generics.requires_monomorphization(tcx) ||
tcx.codegen_fn_attrs(def_id).requests_inline()) && tcx.codegen_fn_attrs(def_id).requests_inline()) &&
!self.metadata_output_only(); !self.metadata_output_only();
let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir;
needs_inline || header.constness == hir::Constness::Const || always_encode_mir needs_inline || sig.header.constness == hir::Constness::Const || always_encode_mir
} }
_ => false, _ => false,
}; };

View File

@ -30,17 +30,22 @@ pub fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> Body<'_> {
// Figure out what primary body this item has. // Figure out what primary body this item has.
let (body_id, return_ty_span) = match tcx.hir().get(id) { let (body_id, return_ty_span) = match tcx.hir().get(id) {
Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. }) Node::Expr(hir::Expr { kind: hir::ExprKind::Closure(_, decl, body_id, _, _), .. })
| Node::Item(hir::Item { kind: hir::ItemKind::Fn(decl, _, _, body_id), .. }) | Node::Item(
hir::Item {
kind: hir::ItemKind::Fn(hir::FnSig { decl, .. }, _, body_id),
..
}
)
| Node::ImplItem( | Node::ImplItem(
hir::ImplItem { hir::ImplItem {
kind: hir::ImplItemKind::Method(hir::MethodSig { decl, .. }, body_id), kind: hir::ImplItemKind::Method(hir::FnSig { decl, .. }, body_id),
.. ..
} }
) )
| Node::TraitItem( | Node::TraitItem(
hir::TraitItem { hir::TraitItem {
kind: hir::TraitItemKind::Method( kind: hir::TraitItemKind::Method(
hir::MethodSig { decl, .. }, hir::FnSig { decl, .. },
hir::TraitMethod::Provided(body_id), hir::TraitMethod::Provided(body_id),
), ),
.. ..

View File

@ -118,7 +118,7 @@ fn op_to_const<'tcx>(
0, 0,
), ),
}; };
let len = b.to_usize(&ecx.tcx.tcx).unwrap(); let len = b.to_machine_usize(&ecx.tcx.tcx).unwrap();
let start = start.try_into().unwrap(); let start = start.try_into().unwrap();
let len: usize = len.try_into().unwrap(); let len: usize = len.try_into().unwrap();
ConstValue::Slice { ConstValue::Slice {

View File

@ -447,7 +447,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
} }
ty::Slice(_) | ty::Str => { ty::Slice(_) | ty::Str => {
let len = metadata.expect("slice fat ptr must have vtable").to_usize(self)?; let len = metadata.expect("slice fat ptr must have length").to_machine_usize(self)?;
let elem = layout.field(self, 0)?; let elem = layout.field(self, 0)?;
// Make sure the slice is not too big. // Make sure the slice is not too big.

View File

@ -228,7 +228,7 @@ for
ty::Array(_, n) ty::Array(_, n)
if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {} if n.eval_usize(self.ecx.tcx.tcx, self.ecx.param_env) == 0 => {}
ty::Slice(_) ty::Slice(_)
if mplace.meta.unwrap().to_usize(self.ecx)? == 0 => {} if mplace.meta.unwrap().to_machine_usize(self.ecx)? == 0 => {}
_ => bug!("const qualif failed to prevent mutable references"), _ => bug!("const qualif failed to prevent mutable references"),
} }
}, },

View File

@ -263,8 +263,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
// This is the dual to the special exception for offset-by-0 // This is the dual to the special exception for offset-by-0
// in the inbounds pointer offset operation (see the Miri code, `src/operator.rs`). // in the inbounds pointer offset operation (see the Miri code, `src/operator.rs`).
if a.is_bits() && b.is_bits() { if a.is_bits() && b.is_bits() {
let a = a.to_usize(self)?; let a = a.to_machine_usize(self)?;
let b = b.to_usize(self)?; let b = b.to_machine_usize(self)?;
if a == b && a != 0 { if a == b && a != 0 {
self.write_scalar(Scalar::from_int(0, isize_layout.size), dest)?; self.write_scalar(Scalar::from_int(0, isize_layout.size), dest)?;
return Ok(true); return Ok(true);

View File

@ -37,7 +37,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let col_out = self.force_ptr(self.mplace_field(location, 2)?.ptr)?; let col_out = self.force_ptr(self.mplace_field(location, 2)?.ptr)?;
let layout = &self.tcx.data_layout; let layout = &self.tcx.data_layout;
let alloc = self.memory.get_mut(file_ptr_out.alloc_id)?; // We just allocated this, so we can skip the bounds checks.
let alloc = self.memory.get_raw_mut(file_ptr_out.alloc_id)?;
alloc.write_scalar(layout, file_ptr_out, file.into(), ptr_size)?; alloc.write_scalar(layout, file_ptr_out, file.into(), ptr_size)?;
alloc.write_scalar(layout, file_len_out, file_len.into(), ptr_size)?; alloc.write_scalar(layout, file_len_out, file_len.into(), ptr_size)?;

View File

@ -210,7 +210,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
let new_ptr = self.allocate(new_size, new_align, kind); let new_ptr = self.allocate(new_size, new_align, kind);
let old_size = match old_size_and_align { let old_size = match old_size_and_align {
Some((size, _align)) => size, Some((size, _align)) => size,
None => self.get(ptr.alloc_id)?.size, None => self.get_raw(ptr.alloc_id)?.size,
}; };
self.copy( self.copy(
ptr, ptr,
@ -480,7 +480,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
).0) ).0)
} }
pub fn get( /// Gives raw access to the `Allocation`, without bounds or alignment checks.
/// Use the higher-level, `PlaceTy`- and `OpTy`-based APIs in `InterpCtx` instead!
pub fn get_raw(
&self, &self,
id: AllocId, id: AllocId,
) -> InterpResult<'tcx, &Allocation<M::PointerTag, M::AllocExtra>> { ) -> InterpResult<'tcx, &Allocation<M::PointerTag, M::AllocExtra>> {
@ -513,7 +515,9 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
} }
} }
pub fn get_mut( /// Gives raw mutable access to the `Allocation`, without bounds or alignment checks.
/// Use the higher-level, `PlaceTy`- and `OpTy`-based APIs in `InterpCtx` instead!
pub fn get_raw_mut(
&mut self, &mut self,
id: AllocId, id: AllocId,
) -> InterpResult<'tcx, &mut Allocation<M::PointerTag, M::AllocExtra>> { ) -> InterpResult<'tcx, &mut Allocation<M::PointerTag, M::AllocExtra>> {
@ -555,7 +559,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
liveness: AllocCheck, liveness: AllocCheck,
) -> InterpResult<'static, (Size, Align)> { ) -> InterpResult<'static, (Size, Align)> {
// # Regular allocations // # Regular allocations
// Don't use `self.get` here as that will // Don't use `self.get_raw` here as that will
// a) cause cycles in case `id` refers to a static // a) cause cycles in case `id` refers to a static
// b) duplicate a static's allocation in miri // b) duplicate a static's allocation in miri
if let Some((_, alloc)) = self.alloc_map.get(id) { if let Some((_, alloc)) = self.alloc_map.get(id) {
@ -627,7 +631,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
} }
pub fn mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> { pub fn mark_immutable(&mut self, id: AllocId) -> InterpResult<'tcx> {
self.get_mut(id)?.mutability = Mutability::Immutable; self.get_raw_mut(id)?.mutability = Mutability::Immutable;
Ok(()) Ok(())
} }
@ -776,7 +780,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
Some(ptr) => ptr, Some(ptr) => ptr,
None => return Ok(&[]), // zero-sized access None => return Ok(&[]), // zero-sized access
}; };
self.get(ptr.alloc_id)?.get_bytes(self, ptr, size) self.get_raw(ptr.alloc_id)?.get_bytes(self, ptr, size)
} }
/// Reads a 0-terminated sequence of bytes from memory. Returns them as a slice. /// Reads a 0-terminated sequence of bytes from memory. Returns them as a slice.
@ -784,7 +788,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
/// Performs appropriate bounds checks. /// Performs appropriate bounds checks.
pub fn read_c_str(&self, ptr: Scalar<M::PointerTag>) -> InterpResult<'tcx, &[u8]> { pub fn read_c_str(&self, ptr: Scalar<M::PointerTag>) -> InterpResult<'tcx, &[u8]> {
let ptr = self.force_ptr(ptr)?; // We need to read at least 1 byte, so we *need* a ptr. let ptr = self.force_ptr(ptr)?; // We need to read at least 1 byte, so we *need* a ptr.
self.get(ptr.alloc_id)?.read_c_str(self, ptr) self.get_raw(ptr.alloc_id)?.read_c_str(self, ptr)
} }
/// Writes the given stream of bytes into memory. /// Writes the given stream of bytes into memory.
@ -804,7 +808,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
None => return Ok(()), // zero-sized access None => return Ok(()), // zero-sized access
}; };
let tcx = self.tcx.tcx; let tcx = self.tcx.tcx;
self.get_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src) self.get_raw_mut(ptr.alloc_id)?.write_bytes(&tcx, ptr, src)
} }
/// Expects the caller to have checked bounds and alignment. /// Expects the caller to have checked bounds and alignment.
@ -832,16 +836,16 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
// since we don't want to keep any relocations at the target. // since we don't want to keep any relocations at the target.
// (`get_bytes_with_undef_and_ptr` below checks that there are no // (`get_bytes_with_undef_and_ptr` below checks that there are no
// relocations overlapping the edges; those would not be handled correctly). // relocations overlapping the edges; those would not be handled correctly).
let relocations = self.get(src.alloc_id)? let relocations = self.get_raw(src.alloc_id)?
.prepare_relocation_copy(self, src, size, dest, length); .prepare_relocation_copy(self, src, size, dest, length);
let tcx = self.tcx.tcx; let tcx = self.tcx.tcx;
// This checks relocation edges on the src. // This checks relocation edges on the src.
let src_bytes = self.get(src.alloc_id)? let src_bytes = self.get_raw(src.alloc_id)?
.get_bytes_with_undef_and_ptr(&tcx, src, size)? .get_bytes_with_undef_and_ptr(&tcx, src, size)?
.as_ptr(); .as_ptr();
let dest_bytes = self.get_mut(dest.alloc_id)? let dest_bytes = self.get_raw_mut(dest.alloc_id)?
.get_bytes_mut(&tcx, dest, size * length)? .get_bytes_mut(&tcx, dest, size * length)?
.as_mut_ptr(); .as_mut_ptr();
@ -880,7 +884,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
// copy definedness to the destination // copy definedness to the destination
self.copy_undef_mask(src, dest, size, length)?; self.copy_undef_mask(src, dest, size, length)?;
// copy the relocations to the destination // copy the relocations to the destination
self.get_mut(dest.alloc_id)?.mark_relocation_range(relocations); self.get_raw_mut(dest.alloc_id)?.mark_relocation_range(relocations);
Ok(()) Ok(())
} }
@ -899,11 +903,11 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
// The bits have to be saved locally before writing to dest in case src and dest overlap. // The bits have to be saved locally before writing to dest in case src and dest overlap.
assert_eq!(size.bytes() as usize as u64, size.bytes()); assert_eq!(size.bytes() as usize as u64, size.bytes());
let src_alloc = self.get(src.alloc_id)?; let src_alloc = self.get_raw(src.alloc_id)?;
let compressed = src_alloc.compress_undef_range(src, size); let compressed = src_alloc.compress_undef_range(src, size);
// now fill in all the data // now fill in all the data
let dest_allocation = self.get_mut(dest.alloc_id)?; let dest_allocation = self.get_raw_mut(dest.alloc_id)?;
dest_allocation.mark_compressed_undef_range(&compressed, dest, size, repeat); dest_allocation.mark_compressed_undef_range(&compressed, dest, size, repeat);
Ok(()) Ok(())
@ -915,7 +919,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
) -> InterpResult<'tcx, Pointer<M::PointerTag>> { ) -> InterpResult<'tcx, Pointer<M::PointerTag>> {
match scalar { match scalar {
Scalar::Ptr(ptr) => Ok(ptr), Scalar::Ptr(ptr) => Ok(ptr),
_ => M::int_to_ptr(&self, scalar.to_usize(self)?) _ => M::int_to_ptr(&self, scalar.to_machine_usize(self)?)
} }
} }

View File

@ -248,7 +248,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
match mplace.layout.abi { match mplace.layout.abi {
layout::Abi::Scalar(..) => { layout::Abi::Scalar(..) => {
let scalar = self.memory let scalar = self.memory
.get(ptr.alloc_id)? .get_raw(ptr.alloc_id)?
.read_scalar(self, ptr, mplace.layout.size)?; .read_scalar(self, ptr, mplace.layout.size)?;
Ok(Some(ImmTy { Ok(Some(ImmTy {
imm: scalar.into(), imm: scalar.into(),
@ -266,10 +266,10 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
assert!(b_offset.bytes() > 0); // we later use the offset to tell apart the fields assert!(b_offset.bytes() > 0); // we later use the offset to tell apart the fields
let b_ptr = ptr.offset(b_offset, self)?; let b_ptr = ptr.offset(b_offset, self)?;
let a_val = self.memory let a_val = self.memory
.get(ptr.alloc_id)? .get_raw(ptr.alloc_id)?
.read_scalar(self, a_ptr, a_size)?; .read_scalar(self, a_ptr, a_size)?;
let b_val = self.memory let b_val = self.memory
.get(ptr.alloc_id)? .get_raw(ptr.alloc_id)?
.read_scalar(self, b_ptr, b_size)?; .read_scalar(self, b_ptr, b_size)?;
Ok(Some(ImmTy { Ok(Some(ImmTy {
imm: Immediate::ScalarPair(a_val, b_val), imm: Immediate::ScalarPair(a_val, b_val),

View File

@ -195,7 +195,7 @@ impl<'tcx, Tag> MPlaceTy<'tcx, Tag> {
// We need to consult `meta` metadata // We need to consult `meta` metadata
match self.layout.ty.kind { match self.layout.ty.kind {
ty::Slice(..) | ty::Str => ty::Slice(..) | ty::Str =>
return self.mplace.meta.unwrap().to_usize(cx), return self.mplace.meta.unwrap().to_machine_usize(cx),
_ => bug!("len not supported on unsized type {:?}", self.layout.ty), _ => bug!("len not supported on unsized type {:?}", self.layout.ty),
} }
} else { } else {
@ -808,7 +808,7 @@ where
_ => bug!("write_immediate_to_mplace: invalid Scalar layout: {:#?}", _ => bug!("write_immediate_to_mplace: invalid Scalar layout: {:#?}",
dest.layout) dest.layout)
} }
self.memory.get_mut(ptr.alloc_id)?.write_scalar( self.memory.get_raw_mut(ptr.alloc_id)?.write_scalar(
tcx, ptr, scalar, dest.layout.size tcx, ptr, scalar, dest.layout.size
) )
} }
@ -830,10 +830,10 @@ where
// fields do not match the `ScalarPair` components. // fields do not match the `ScalarPair` components.
self.memory self.memory
.get_mut(ptr.alloc_id)? .get_raw_mut(ptr.alloc_id)?
.write_scalar(tcx, ptr, a_val, a_size)?; .write_scalar(tcx, ptr, a_val, a_size)?;
self.memory self.memory
.get_mut(b_ptr.alloc_id)? .get_raw_mut(b_ptr.alloc_id)?
.write_scalar(tcx, b_ptr, b_val, b_size) .write_scalar(tcx, b_ptr, b_val, b_size)
} }
} }

View File

@ -392,7 +392,7 @@ impl<'b, 'mir, 'tcx> SnapshotContext<'b>
for Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>> for Memory<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>
{ {
fn resolve(&'b self, id: &AllocId) -> Option<&'b Allocation> { fn resolve(&'b self, id: &AllocId) -> Option<&'b Allocation> {
self.get(*id).ok() self.get_raw(*id).ok()
} }
} }

View File

@ -445,7 +445,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
ptr_size, ptr_size,
self.tcx.data_layout.pointer_align.abi, self.tcx.data_layout.pointer_align.abi,
)?.expect("cannot be a ZST"); )?.expect("cannot be a ZST");
let fn_ptr = self.memory.get(vtable_slot.alloc_id)? let fn_ptr = self.memory.get_raw(vtable_slot.alloc_id)?
.read_ptr_sized(self, vtable_slot)?.not_undef()?; .read_ptr_sized(self, vtable_slot)?.not_undef()?;
let drop_fn = self.memory.get_fn(fn_ptr)?; let drop_fn = self.memory.get_fn(fn_ptr)?;

View File

@ -63,35 +63,30 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
let drop = Instance::resolve_drop_in_place(*tcx, ty); let drop = Instance::resolve_drop_in_place(*tcx, ty);
let drop = self.memory.create_fn_alloc(FnVal::Instance(drop)); let drop = self.memory.create_fn_alloc(FnVal::Instance(drop));
// no need to do any alignment checks on the memory accesses below, because we know the // No need to do any alignment checks on the memory accesses below, because we know the
// allocation is correctly aligned as we created it above. Also we're only offsetting by // allocation is correctly aligned as we created it above. Also we're only offsetting by
// multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`. // multiples of `ptr_align`, which means that it will stay aligned to `ptr_align`.
self.memory let vtable_alloc = self.memory.get_raw_mut(vtable.alloc_id)?;
.get_mut(vtable.alloc_id)? vtable_alloc.write_ptr_sized(tcx, vtable, Scalar::Ptr(drop).into())?;
.write_ptr_sized(tcx, vtable, Scalar::Ptr(drop).into())?;
let size_ptr = vtable.offset(ptr_size, self)?; let size_ptr = vtable.offset(ptr_size, tcx)?;
self.memory vtable_alloc.write_ptr_sized(tcx, size_ptr, Scalar::from_uint(size, ptr_size).into())?;
.get_mut(size_ptr.alloc_id)? let align_ptr = vtable.offset(ptr_size * 2, tcx)?;
.write_ptr_sized(tcx, size_ptr, Scalar::from_uint(size, ptr_size).into())?; vtable_alloc.write_ptr_sized(tcx, align_ptr, Scalar::from_uint(align, ptr_size).into())?;
let align_ptr = vtable.offset(ptr_size * 2, self)?;
self.memory
.get_mut(align_ptr.alloc_id)?
.write_ptr_sized(tcx, align_ptr, Scalar::from_uint(align, ptr_size).into())?;
for (i, method) in methods.iter().enumerate() { for (i, method) in methods.iter().enumerate() {
if let Some((def_id, substs)) = *method { if let Some((def_id, substs)) = *method {
// resolve for vtable: insert shims where needed // resolve for vtable: insert shims where needed
let instance = ty::Instance::resolve_for_vtable( let instance = ty::Instance::resolve_for_vtable(
*self.tcx, *tcx,
self.param_env, self.param_env,
def_id, def_id,
substs, substs,
).ok_or_else(|| err_inval!(TooGeneric))?; ).ok_or_else(|| err_inval!(TooGeneric))?;
let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance)); let fn_ptr = self.memory.create_fn_alloc(FnVal::Instance(instance));
let method_ptr = vtable.offset(ptr_size * (3 + i as u64), self)?; // We cannot use `vtable_allic` as we are creating fn ptrs in this loop.
self.memory let method_ptr = vtable.offset(ptr_size * (3 + i as u64), tcx)?;
.get_mut(method_ptr.alloc_id)? self.memory.get_raw_mut(vtable.alloc_id)?
.write_ptr_sized(tcx, method_ptr, Scalar::Ptr(fn_ptr).into())?; .write_ptr_sized(tcx, method_ptr, Scalar::Ptr(fn_ptr).into())?;
} }
} }
@ -114,7 +109,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
self.tcx.data_layout.pointer_align.abi, self.tcx.data_layout.pointer_align.abi,
)?.expect("cannot be a ZST"); )?.expect("cannot be a ZST");
let drop_fn = self.memory let drop_fn = self.memory
.get(vtable.alloc_id)? .get_raw(vtable.alloc_id)?
.read_ptr_sized(self, vtable)? .read_ptr_sized(self, vtable)?
.not_undef()?; .not_undef()?;
// We *need* an instance here, no other kind of function value, to be able // We *need* an instance here, no other kind of function value, to be able
@ -140,7 +135,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
3*pointer_size, 3*pointer_size,
self.tcx.data_layout.pointer_align.abi, self.tcx.data_layout.pointer_align.abi,
)?.expect("cannot be a ZST"); )?.expect("cannot be a ZST");
let alloc = self.memory.get(vtable.alloc_id)?; let alloc = self.memory.get_raw(vtable.alloc_id)?;
let size = alloc.read_ptr_sized( let size = alloc.read_ptr_sized(
self, self,
vtable.offset(pointer_size, self)? vtable.offset(pointer_size, self)?

View File

@ -282,7 +282,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, 'tcx, M
// FIXME: More checks for the vtable. // FIXME: More checks for the vtable.
} }
ty::Slice(..) | ty::Str => { ty::Slice(..) | ty::Str => {
let _len = try_validation!(meta.unwrap().to_usize(self.ecx), let _len = try_validation!(meta.unwrap().to_machine_usize(self.ecx),
"non-integer slice length in wide pointer", self.path); "non-integer slice length in wide pointer", self.path);
// We do not check that `len * elem_size <= isize::MAX`: // We do not check that `len * elem_size <= isize::MAX`:
// that is only required for references, and there it falls out of the // that is only required for references, and there it falls out of the
@ -586,6 +586,8 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
_ => false, _ => false,
} }
} => { } => {
// Optimized handling for arrays of integer/float type.
// bailing out for zsts is ok, since the array element type can only be int/float // bailing out for zsts is ok, since the array element type can only be int/float
if op.layout.is_zst() { if op.layout.is_zst() {
return Ok(()); return Ok(());
@ -605,6 +607,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// Size is not 0, get a pointer. // Size is not 0, get a pointer.
let ptr = self.ecx.force_ptr(mplace.ptr)?; let ptr = self.ecx.force_ptr(mplace.ptr)?;
// This is the optimization: we just check the entire range at once.
// NOTE: Keep this in sync with the handling of integer and float // NOTE: Keep this in sync with the handling of integer and float
// types above, in `visit_primitive`. // types above, in `visit_primitive`.
// In run-time mode, we accept pointers in here. This is actually more // In run-time mode, we accept pointers in here. This is actually more
@ -614,7 +617,7 @@ impl<'rt, 'mir, 'tcx, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
// to reject those pointers, we just do not have the machinery to // to reject those pointers, we just do not have the machinery to
// talk about parts of a pointer. // talk about parts of a pointer.
// We also accept undef, for consistency with the slow path. // We also accept undef, for consistency with the slow path.
match self.ecx.memory.get(ptr.alloc_id)?.check_bytes( match self.ecx.memory.get_raw(ptr.alloc_id)?.check_bytes(
self.ecx, self.ecx,
ptr, ptr,
size, size,

View File

@ -1071,7 +1071,7 @@ impl ItemLikeVisitor<'v> for RootCollector<'_, 'v> {
fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) { fn visit_impl_item(&mut self, ii: &'v hir::ImplItem) {
match ii.kind { match ii.kind {
hir::ImplItemKind::Method(hir::MethodSig { .. }, _) => { hir::ImplItemKind::Method(hir::FnSig { .. }, _) => {
let def_id = self.tcx.hir().local_def_id(ii.hir_id); let def_id = self.tcx.hir().local_def_id(ii.hir_id);
self.push_if_root(def_id); self.push_if_root(def_id);
} }

View File

@ -8,7 +8,7 @@ use rustc::ty::cast::CastTy;
use rustc::hir; use rustc::hir;
use rustc::hir::Node; use rustc::hir::Node;
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::lint::builtin::{SAFE_EXTERN_STATICS, SAFE_PACKED_BORROWS, UNUSED_UNSAFE}; use rustc::lint::builtin::{SAFE_PACKED_BORROWS, UNUSED_UNSAFE};
use rustc::mir::*; use rustc::mir::*;
use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext}; use rustc::mir::visit::{PlaceContext, Visitor, MutatingUseContext};
@ -208,23 +208,20 @@ impl<'a, 'tcx> Visitor<'tcx> for UnsafetyChecker<'a, 'tcx> {
} }
PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => { PlaceBase::Static(box Static { kind: StaticKind::Static, def_id, .. }) => {
if self.tcx.is_mutable_static(def_id) { if self.tcx.is_mutable_static(def_id) {
self.require_unsafe("use of mutable static", self.require_unsafe(
"use of mutable static",
"mutable statics can be mutated by multiple threads: aliasing \ "mutable statics can be mutated by multiple threads: aliasing \
violations or data races will cause undefined behavior", violations or data races will cause undefined behavior",
UnsafetyViolationKind::General); UnsafetyViolationKind::General,
);
} else if self.tcx.is_foreign_item(def_id) { } else if self.tcx.is_foreign_item(def_id) {
let source_info = self.source_info; self.require_unsafe(
let lint_root = "use of extern static",
self.source_scope_local_data[source_info.scope].lint_root;
self.register_violations(&[UnsafetyViolation {
source_info,
description: Symbol::intern("use of extern static"),
details: Symbol::intern(
"extern statics are not controlled by the Rust type system: \ "extern statics are not controlled by the Rust type system: \
invalid data, aliasing violations or data races will cause \ invalid data, aliasing violations or data races will cause \
undefined behavior"), undefined behavior",
kind: UnsafetyViolationKind::ExternStatic(lint_root) UnsafetyViolationKind::General,
}], &[]); );
} }
} }
} }
@ -351,8 +348,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
match violation.kind { match violation.kind {
UnsafetyViolationKind::GeneralAndConstFn | UnsafetyViolationKind::GeneralAndConstFn |
UnsafetyViolationKind::General => {}, UnsafetyViolationKind::General => {},
UnsafetyViolationKind::BorrowPacked(_) | UnsafetyViolationKind::BorrowPacked(_) => if self.min_const_fn {
UnsafetyViolationKind::ExternStatic(_) => if self.min_const_fn {
// const fns don't need to be backwards compatible and can // const fns don't need to be backwards compatible and can
// emit these violations as a hard error instead of a backwards // emit these violations as a hard error instead of a backwards
// compat lint // compat lint
@ -380,8 +376,7 @@ impl<'a, 'tcx> UnsafetyChecker<'a, 'tcx> {
UnsafetyViolationKind::GeneralAndConstFn => {}, UnsafetyViolationKind::GeneralAndConstFn => {},
// these things are forbidden in const fns // these things are forbidden in const fns
UnsafetyViolationKind::General | UnsafetyViolationKind::General |
UnsafetyViolationKind::BorrowPacked(_) | UnsafetyViolationKind::BorrowPacked(_) => {
UnsafetyViolationKind::ExternStatic(_) => {
let mut violation = violation.clone(); let mut violation = violation.clone();
// const fns don't need to be backwards compatible and can // const fns don't need to be backwards compatible and can
// emit these violations as a hard error instead of a backwards // emit these violations as a hard error instead of a backwards
@ -576,10 +571,10 @@ fn is_enclosed(
if used_unsafe.contains(&parent_id) { if used_unsafe.contains(&parent_id) {
Some(("block".to_string(), parent_id)) Some(("block".to_string(), parent_id))
} else if let Some(Node::Item(&hir::Item { } else if let Some(Node::Item(&hir::Item {
kind: hir::ItemKind::Fn(_, header, _, _), kind: hir::ItemKind::Fn(ref sig, _, _),
.. ..
})) = tcx.hir().find(parent_id) { })) = tcx.hir().find(parent_id) {
match header.unsafety { match sig.header.unsafety {
hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)), hir::Unsafety::Unsafe => Some(("fn".to_string(), parent_id)),
hir::Unsafety::Normal => None, hir::Unsafety::Normal => None,
} }
@ -646,14 +641,6 @@ pub fn check_unsafety(tcx: TyCtxt<'_>, def_id: DefId) {
.note(&details.as_str()) .note(&details.as_str())
.emit(); .emit();
} }
UnsafetyViolationKind::ExternStatic(lint_hir_id) => {
tcx.lint_node_note(SAFE_EXTERN_STATICS,
lint_hir_id,
source_info.span,
&format!("{} is unsafe and requires unsafe function or block \
(error E0133)", description),
&details.as_str());
}
UnsafetyViolationKind::BorrowPacked(lint_hir_id) => { UnsafetyViolationKind::BorrowPacked(lint_hir_id) => {
if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) { if let Some(impl_def_id) = builtin_derive_def_id(tcx, def_id) {
tcx.unsafe_derive_on_repr_packed(impl_def_id); tcx.unsafe_derive_on_repr_packed(impl_def_id);

View File

@ -9,7 +9,6 @@
use std::mem; use std::mem;
use syntax::print::pprust; use syntax::print::pprust;
use rustc::lint; use rustc::lint;
use rustc::lint::builtin::{BuiltinLintDiagnostics, NESTED_IMPL_TRAIT};
use rustc::session::Session; use rustc::session::Session;
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use syntax::ast::*; use syntax::ast::*;
@ -23,31 +22,6 @@ use syntax::{span_err, struct_span_err, walk_list};
use syntax_pos::{Span, MultiSpan}; use syntax_pos::{Span, MultiSpan};
use errors::{Applicability, FatalError}; use errors::{Applicability, FatalError};
#[derive(Copy, Clone, Debug)]
struct OuterImplTrait {
span: Span,
/// rust-lang/rust#57979: a bug in original implementation caused
/// us to fail sometimes to record an outer `impl Trait`.
/// Therefore, in order to reliably issue a warning (rather than
/// an error) in the *precise* places where we are newly injecting
/// the diagnostic, we have to distinguish between the places
/// where the outer `impl Trait` has always been recorded, versus
/// the places where it has only recently started being recorded.
only_recorded_since_pull_request_57730: bool,
}
impl OuterImplTrait {
/// This controls whether we should downgrade the nested impl
/// trait diagnostic to a warning rather than an error, based on
/// whether the outer impl trait had been improperly skipped in
/// earlier implementations of the analysis on the stable
/// compiler.
fn should_warn_instead_of_error(&self) -> bool {
self.only_recorded_since_pull_request_57730
}
}
struct AstValidator<'a> { struct AstValidator<'a> {
session: &'a Session, session: &'a Session,
has_proc_macro_decls: bool, has_proc_macro_decls: bool,
@ -55,7 +29,7 @@ struct AstValidator<'a> {
/// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`. /// Used to ban nested `impl Trait`, e.g., `impl Into<impl Debug>`.
/// Nested `impl Trait` _is_ allowed in associated type position, /// Nested `impl Trait` _is_ allowed in associated type position,
/// e.g., `impl Iterator<Item = impl Debug>`. /// e.g., `impl Iterator<Item = impl Debug>`.
outer_impl_trait: Option<OuterImplTrait>, outer_impl_trait: Option<Span>,
/// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item` /// Used to ban `impl Trait` in path projections like `<impl Iterator>::Item`
/// or `Foo::Bar<impl Trait>` /// or `Foo::Bar<impl Trait>`
@ -65,26 +39,10 @@ struct AstValidator<'a> {
/// certain positions. /// certain positions.
is_assoc_ty_bound_banned: bool, is_assoc_ty_bound_banned: bool,
/// rust-lang/rust#57979: the ban of nested `impl Trait` was buggy
/// until PRs #57730 and #57981 landed: it would jump directly to
/// walk_ty rather than visit_ty (or skip recurring entirely for
/// impl trait in projections), and thus miss some cases. We track
/// whether we should downgrade to a warning for short-term via
/// these booleans.
warning_period_57979_didnt_record_next_impl_trait: bool,
warning_period_57979_impl_trait_in_proj: bool,
lint_buffer: &'a mut lint::LintBuffer, lint_buffer: &'a mut lint::LintBuffer,
} }
impl<'a> AstValidator<'a> { impl<'a> AstValidator<'a> {
fn with_impl_trait_in_proj_warning<T>(&mut self, v: bool, f: impl FnOnce(&mut Self) -> T) -> T {
let old = mem::replace(&mut self.warning_period_57979_impl_trait_in_proj, v);
let ret = f(self);
self.warning_period_57979_impl_trait_in_proj = old;
ret
}
fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) { fn with_banned_impl_trait(&mut self, f: impl FnOnce(&mut Self)) {
let old = mem::replace(&mut self.is_impl_trait_banned, true); let old = mem::replace(&mut self.is_impl_trait_banned, true);
f(self); f(self);
@ -97,7 +55,7 @@ impl<'a> AstValidator<'a> {
self.is_assoc_ty_bound_banned = old; self.is_assoc_ty_bound_banned = old;
} }
fn with_impl_trait(&mut self, outer: Option<OuterImplTrait>, f: impl FnOnce(&mut Self)) { fn with_impl_trait(&mut self, outer: Option<Span>, f: impl FnOnce(&mut Self)) {
let old = mem::replace(&mut self.outer_impl_trait, outer); let old = mem::replace(&mut self.outer_impl_trait, outer);
f(self); f(self);
self.outer_impl_trait = old; self.outer_impl_trait = old;
@ -105,14 +63,7 @@ impl<'a> AstValidator<'a> {
fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) { fn visit_assoc_ty_constraint_from_generic_args(&mut self, constraint: &'a AssocTyConstraint) {
match constraint.kind { match constraint.kind {
AssocTyConstraintKind::Equality { ref ty } => { AssocTyConstraintKind::Equality { .. } => {}
// rust-lang/rust#57979: bug in old `visit_generic_args` called
// `walk_ty` rather than `visit_ty`, skipping outer `impl Trait`
// if it happened to occur at `ty`.
if let TyKind::ImplTrait(..) = ty.kind {
self.warning_period_57979_didnt_record_next_impl_trait = true;
}
}
AssocTyConstraintKind::Bound { .. } => { AssocTyConstraintKind::Bound { .. } => {
if self.is_assoc_ty_bound_banned { if self.is_assoc_ty_bound_banned {
self.err_handler().span_err(constraint.span, self.err_handler().span_err(constraint.span,
@ -124,37 +75,11 @@ impl<'a> AstValidator<'a> {
self.visit_assoc_ty_constraint(constraint); self.visit_assoc_ty_constraint(constraint);
} }
fn visit_ty_from_generic_args(&mut self, ty: &'a Ty) {
// rust-lang/rust#57979: bug in old `visit_generic_args` called
// `walk_ty` rather than `visit_ty`, skippping outer `impl Trait`
// if it happened to occur at `ty`.
if let TyKind::ImplTrait(..) = ty.kind {
self.warning_period_57979_didnt_record_next_impl_trait = true;
}
self.visit_ty(ty);
}
fn outer_impl_trait(&mut self, span: Span) -> OuterImplTrait {
let only_recorded_since_pull_request_57730 =
self.warning_period_57979_didnt_record_next_impl_trait;
// (This flag is designed to be set to `true`, and then only
// reach the construction point for the outer impl trait once,
// so its safe and easiest to unconditionally reset it to
// false.)
self.warning_period_57979_didnt_record_next_impl_trait = false;
OuterImplTrait {
span, only_recorded_since_pull_request_57730,
}
}
// Mirrors `visit::walk_ty`, but tracks relevant state. // Mirrors `visit::walk_ty`, but tracks relevant state.
fn walk_ty(&mut self, t: &'a Ty) { fn walk_ty(&mut self, t: &'a Ty) {
match t.kind { match t.kind {
TyKind::ImplTrait(..) => { TyKind::ImplTrait(..) => {
let outer_impl_trait = self.outer_impl_trait(t.span); self.with_impl_trait(Some(t.span), |this| visit::walk_ty(this, t))
self.with_impl_trait(Some(outer_impl_trait), |this| visit::walk_ty(this, t))
} }
TyKind::Path(ref qself, ref path) => { TyKind::Path(ref qself, ref path) => {
// We allow these: // We allow these:
@ -484,32 +409,21 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
TyKind::ImplTrait(_, ref bounds) => { TyKind::ImplTrait(_, ref bounds) => {
if self.is_impl_trait_banned { if self.is_impl_trait_banned {
if self.warning_period_57979_impl_trait_in_proj { struct_span_err!(
self.lint_buffer.buffer_lint( self.session, ty.span, E0667,
NESTED_IMPL_TRAIT, ty.id, ty.span, "`impl Trait` is not allowed in path parameters"
"`impl Trait` is not allowed in path parameters"); )
} else {
struct_span_err!(self.session, ty.span, E0667,
"`impl Trait` is not allowed in path parameters").emit();
}
}
if let Some(outer_impl_trait) = self.outer_impl_trait {
if outer_impl_trait.should_warn_instead_of_error() {
self.lint_buffer.buffer_lint_with_diagnostic(
NESTED_IMPL_TRAIT, ty.id, ty.span,
"nested `impl Trait` is not allowed",
BuiltinLintDiagnostics::NestedImplTrait {
outer_impl_trait_span: outer_impl_trait.span,
inner_impl_trait_span: ty.span,
});
} else {
struct_span_err!(self.session, ty.span, E0666,
"nested `impl Trait` is not allowed")
.span_label(outer_impl_trait.span, "outer `impl Trait`")
.span_label(ty.span, "nested `impl Trait` here")
.emit(); .emit();
} }
if let Some(outer_impl_trait_sp) = self.outer_impl_trait {
struct_span_err!(
self.session, ty.span, E0666,
"nested `impl Trait` is not allowed"
)
.span_label(outer_impl_trait_sp, "outer `impl Trait`")
.span_label(ty.span, "nested `impl Trait` here")
.emit();
} }
if !bounds.iter() if !bounds.iter()
@ -517,7 +431,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
self.err_handler().span_err(ty.span, "at least one trait must be specified"); self.err_handler().span_err(ty.span, "at least one trait must be specified");
} }
self.with_impl_trait_in_proj_warning(true, |this| this.walk_ty(ty)); self.walk_ty(ty);
return; return;
} }
_ => {} _ => {}
@ -575,12 +489,12 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
.note("only trait implementations may be annotated with default").emit(); .note("only trait implementations may be annotated with default").emit();
} }
} }
ItemKind::Fn(ref decl, ref header, ref generics, _) => { ItemKind::Fn(ref sig, ref generics, _) => {
self.visit_fn_header(header); self.visit_fn_header(&sig.header);
self.check_fn_decl(decl); self.check_fn_decl(&sig.decl);
// We currently do not permit const generics in `const fn`, as // We currently do not permit const generics in `const fn`, as
// this is tantamount to allowing compile-time dependent typing. // this is tantamount to allowing compile-time dependent typing.
if header.constness.node == Constness::Const { if sig.header.constness.node == Constness::Const {
// Look for const generics and error if we find any. // Look for const generics and error if we find any.
for param in &generics.params { for param in &generics.params {
match param.kind { match param.kind {
@ -654,11 +568,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
ItemKind::Mod(_) => { ItemKind::Mod(_) => {
// Ensure that `path` attributes on modules are recorded as used (cf. issue #35584). // Ensure that `path` attributes on modules are recorded as used (cf. issue #35584).
attr::first_attr_value_str_by_name(&item.attrs, sym::path); attr::first_attr_value_str_by_name(&item.attrs, sym::path);
if attr::contains_name(&item.attrs, sym::warn_directory_ownership) {
let lint = lint::builtin::LEGACY_DIRECTORY_OWNERSHIP;
let msg = "cannot declare a new module at this location";
self.lint_buffer.buffer_lint(lint, item.id, item.span, msg);
}
} }
ItemKind::Union(ref vdata, _) => { ItemKind::Union(ref vdata, _) => {
if let VariantData::Tuple(..) | VariantData::Unit(..) = vdata { if let VariantData::Tuple(..) | VariantData::Unit(..) = vdata {
@ -731,7 +640,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
if let Some(ref type_) = data.output { if let Some(ref type_) = data.output {
// `-> Foo` syntax is essentially an associated type binding, // `-> Foo` syntax is essentially an associated type binding,
// so it is also allowed to contain nested `impl Trait`. // so it is also allowed to contain nested `impl Trait`.
self.with_impl_trait(None, |this| this.visit_ty_from_generic_args(type_)); self.with_impl_trait(None, |this| this.visit_ty(type_));
} }
} }
} }
@ -849,8 +758,6 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut lint::LintBuffe
outer_impl_trait: None, outer_impl_trait: None,
is_impl_trait_banned: false, is_impl_trait_banned: false,
is_assoc_ty_bound_banned: false, is_assoc_ty_bound_banned: false,
warning_period_57979_didnt_record_next_impl_trait: false,
warning_period_57979_impl_trait_in_proj: false,
lint_buffer: lints, lint_buffer: lints,
}; };
visit::walk_crate(&mut validator, krate); visit::walk_crate(&mut validator, krate);

View File

@ -731,7 +731,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
match item.kind { match item.kind {
ItemKind::TyAlias(_, ref generics) | ItemKind::TyAlias(_, ref generics) |
ItemKind::OpaqueTy(_, ref generics) | ItemKind::OpaqueTy(_, ref generics) |
ItemKind::Fn(_, _, ref generics, _) => { ItemKind::Fn(_, ref generics, _) => {
self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes), self.with_generic_param_rib(generics, ItemRibKind(HasGenericParams::Yes),
|this| visit::walk_item(this, item)); |this| visit::walk_item(this, item));
} }
@ -1539,25 +1539,7 @@ impl<'a, 'b> LateResolutionVisitor<'a, '_> {
if is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err { if is_expected(partial_res.base_res()) || partial_res.base_res() == Res::Err {
partial_res partial_res
} else { } else {
// Add a temporary hack to smooth the transition to new struct ctor report_errors(self, Some(partial_res.base_res()))
// visibility rules. See #38932 for more details.
let mut res = None;
if let Res::Def(DefKind::Struct, def_id) = partial_res.base_res() {
if let Some((ctor_res, ctor_vis))
= self.r.struct_constructors.get(&def_id).cloned() {
if is_expected(ctor_res) &&
self.r.is_accessible_from(ctor_vis, self.parent_scope.module) {
let lint = lint::builtin::LEGACY_CONSTRUCTOR_VISIBILITY;
self.r.lint_buffer.buffer_lint(lint, id, span,
"private struct constructors are not usable through \
re-exports in outer modules",
);
res = Some(PartialRes::new(ctor_res));
}
}
}
res.unwrap_or_else(|| report_errors(self, Some(partial_res.base_res())))
} }
} }
Some(partial_res) if source.defer_to_typeck() => { Some(partial_res) if source.defer_to_typeck() => {

View File

@ -16,18 +16,14 @@ use errors::{Applicability, pluralize};
use rustc_data_structures::ptr_key::PtrKey; use rustc_data_structures::ptr_key::PtrKey;
use rustc::ty; use rustc::ty;
use rustc::lint::builtin::BuiltinLintDiagnostics; use rustc::lint::builtin::BuiltinLintDiagnostics;
use rustc::lint::builtin::{ use rustc::lint::builtin::{PUB_USE_OF_PRIVATE_EXTERN_CRATE, UNUSED_IMPORTS};
DUPLICATE_MACRO_EXPORTS,
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
UNUSED_IMPORTS,
};
use rustc::hir::def_id::DefId; use rustc::hir::def_id::DefId;
use rustc::hir::def::{self, PartialRes, Export}; use rustc::hir::def::{self, PartialRes, Export};
use rustc::session::DiagnosticMessageId; use rustc::session::DiagnosticMessageId;
use rustc::util::nodemap::FxHashSet; use rustc::util::nodemap::FxHashSet;
use rustc::{bug, span_bug}; use rustc::{bug, span_bug};
use syntax::ast::{Ident, Name, NodeId, CRATE_NODE_ID}; use syntax::ast::{Ident, Name, NodeId};
use syntax::symbol::kw; use syntax::symbol::kw;
use syntax::util::lev_distance::find_best_match_for_name; use syntax::util::lev_distance::find_best_match_for_name;
use syntax::{struct_span_err, unwrap_or}; use syntax::{struct_span_err, unwrap_or};
@ -496,13 +492,13 @@ impl<'a> Resolver<'a> {
if let (&NameBindingKind::Res(_, true), &NameBindingKind::Res(_, true)) = if let (&NameBindingKind::Res(_, true), &NameBindingKind::Res(_, true)) =
(&old_binding.kind, &binding.kind) { (&old_binding.kind, &binding.kind) {
this.lint_buffer.buffer_lint_with_diagnostic( this.session.struct_span_err(
DUPLICATE_MACRO_EXPORTS,
CRATE_NODE_ID,
binding.span, binding.span,
&format!("a macro named `{}` has already been exported", key.ident), &format!("a macro named `{}` has already been exported", key.ident),
BuiltinLintDiagnostics::DuplicatedMacroExports( )
key.ident, old_binding.span, binding.span)); .span_label(binding.span, format!("`{}` already exported", key.ident))
.span_note(old_binding.span, "previous macro export is now shadowed")
.emit();
resolution.binding = Some(binding); resolution.binding = Some(binding);
} else { } else {

View File

@ -272,7 +272,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
fn process_method( fn process_method(
&mut self, &mut self,
sig: &'l ast::MethodSig, sig: &'l ast::FnSig,
body: Option<&'l ast::Block>, body: Option<&'l ast::Block>,
id: ast::NodeId, id: ast::NodeId,
ident: ast::Ident, ident: ast::Ident,
@ -1334,8 +1334,8 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
); );
} }
} }
Fn(ref decl, ref header, ref ty_params, ref body) => { Fn(ref sig, ref ty_params, ref body) => {
self.process_fn(item, &decl, &header, ty_params, &body) self.process_fn(item, &sig.decl, &sig.header, ty_params, &body)
} }
Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr), Static(ref typ, _, ref expr) => self.process_static_or_const_item(item, typ, expr),
Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr), Const(ref typ, ref expr) => self.process_static_or_const_item(item, &typ, &expr),

View File

@ -180,7 +180,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> { pub fn get_item_data(&self, item: &ast::Item) -> Option<Data> {
match item.kind { match item.kind {
ast::ItemKind::Fn(ref decl, .., ref generics, _) => { ast::ItemKind::Fn(ref sig, .., ref generics, _) => {
let qualname = format!("::{}", let qualname = format!("::{}",
self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id))); self.tcx.def_path_str(self.tcx.hir().local_def_id_from_node_id(item.id)));
filter!(self.span_utils, item.ident.span); filter!(self.span_utils, item.ident.span);
@ -190,7 +190,7 @@ impl<'l, 'tcx> SaveContext<'l, 'tcx> {
span: self.span_from_span(item.ident.span), span: self.span_from_span(item.ident.span),
name: item.ident.to_string(), name: item.ident.to_string(),
qualname, qualname,
value: make_signature(decl, generics), value: make_signature(&sig.decl, generics),
parent: None, parent: None,
children: vec![], children: vec![],
decl_id: None, decl_id: None,

View File

@ -72,7 +72,7 @@ pub fn method_signature(
id: NodeId, id: NodeId,
ident: ast::Ident, ident: ast::Ident,
generics: &ast::Generics, generics: &ast::Generics,
m: &ast::MethodSig, m: &ast::FnSig,
scx: &SaveContext<'_, '_>, scx: &SaveContext<'_, '_>,
) -> Option<Signature> { ) -> Option<Signature> {
if !scx.config.signatures { if !scx.config.signatures {
@ -376,7 +376,7 @@ impl Sig for ast::Item {
Ok(extend_sig(ty, text, defs, vec![])) Ok(extend_sig(ty, text, defs, vec![]))
} }
ast::ItemKind::Fn(ref decl, header, ref generics, _) => { ast::ItemKind::Fn(ast::FnSig { ref decl, header }, ref generics, _) => {
let mut text = String::new(); let mut text = String::new();
if header.constness.node == ast::Constness::Const { if header.constness.node == ast::Constness::Const {
text.push_str("const "); text.push_str("const ");
@ -932,7 +932,7 @@ fn make_method_signature(
id: NodeId, id: NodeId,
ident: ast::Ident, ident: ast::Ident,
generics: &ast::Generics, generics: &ast::Generics,
m: &ast::MethodSig, m: &ast::FnSig,
scx: &SaveContext<'_, '_>, scx: &SaveContext<'_, '_>,
) -> Result { ) -> Result {
// FIXME code dup with function signature // FIXME code dup with function signature

View File

@ -815,8 +815,8 @@ fn primary_body_of(
hir::ItemKind::Const(ref ty, body) | hir::ItemKind::Const(ref ty, body) |
hir::ItemKind::Static(ref ty, _, body) => hir::ItemKind::Static(ref ty, _, body) =>
Some((body, Some(ty), None, None)), Some((body, Some(ty), None, None)),
hir::ItemKind::Fn(ref decl, ref header, .., body) => hir::ItemKind::Fn(ref sig, .., body) =>
Some((body, None, Some(header), Some(decl))), Some((body, None, Some(&sig.header), Some(&sig.decl))),
_ => _ =>
None, None,
} }
@ -1297,7 +1297,7 @@ fn check_fn<'a, 'tcx>(
} }
if let Node::Item(item) = fcx.tcx.hir().get(fn_id) { if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
if let ItemKind::Fn(_, _, ref generics, _) = item.kind { if let ItemKind::Fn(_, ref generics, _) = item.kind {
if !generics.params.is_empty() { if !generics.params.is_empty() {
fcx.tcx.sess.span_err( fcx.tcx.sess.span_err(
span, span,
@ -1345,7 +1345,7 @@ fn check_fn<'a, 'tcx>(
} }
if let Node::Item(item) = fcx.tcx.hir().get(fn_id) { if let Node::Item(item) = fcx.tcx.hir().get(fn_id) {
if let ItemKind::Fn(_, _, ref generics, _) = item.kind { if let ItemKind::Fn(_, ref generics, _) = item.kind {
if !generics.params.is_empty() { if !generics.params.is_empty() {
fcx.tcx.sess.span_err( fcx.tcx.sess.span_err(
span, span,
@ -4278,7 +4278,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id)); let node = self.tcx.hir().get(self.tcx.hir().get_parent_item(id));
match node { match node {
Node::Item(&hir::Item { Node::Item(&hir::Item {
kind: hir::ItemKind::Fn(_, _, _, body_id), .. kind: hir::ItemKind::Fn(_, _, body_id), ..
}) | }) |
Node::ImplItem(&hir::ImplItem { Node::ImplItem(&hir::ImplItem {
kind: hir::ImplItemKind::Method(_, body_id), .. kind: hir::ImplItemKind::Method(_, body_id), ..
@ -4303,23 +4303,19 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> { fn get_node_fn_decl(&self, node: Node<'tcx>) -> Option<(&'tcx hir::FnDecl, ast::Ident, bool)> {
match node { match node {
Node::Item(&hir::Item { Node::Item(&hir::Item {
ident, kind: hir::ItemKind::Fn(ref decl, ..), .. ident, kind: hir::ItemKind::Fn(ref sig, ..), ..
}) => { }) => {
// This is less than ideal, it will not suggest a return type span on any // This is less than ideal, it will not suggest a return type span on any
// method called `main`, regardless of whether it is actually the entry point, // method called `main`, regardless of whether it is actually the entry point,
// but it will still present it as the reason for the expected type. // but it will still present it as the reason for the expected type.
Some((decl, ident, ident.name != sym::main)) Some((&sig.decl, ident, ident.name != sym::main))
} }
Node::TraitItem(&hir::TraitItem { Node::TraitItem(&hir::TraitItem {
ident, kind: hir::TraitItemKind::Method(hir::MethodSig { ident, kind: hir::TraitItemKind::Method(ref sig, ..), ..
ref decl, .. }) => Some((&sig.decl, ident, true)),
}, ..), ..
}) => Some((decl, ident, true)),
Node::ImplItem(&hir::ImplItem { Node::ImplItem(&hir::ImplItem {
ident, kind: hir::ImplItemKind::Method(hir::MethodSig { ident, kind: hir::ImplItemKind::Method(ref sig, ..), ..
ref decl, .. }) => Some((&sig.decl, ident, false)),
}, ..), ..
}) => Some((decl, ident, false)),
_ => None, _ => None,
} }
} }

View File

@ -190,7 +190,7 @@ fn check_associated_item(
tcx: TyCtxt<'_>, tcx: TyCtxt<'_>,
item_id: hir::HirId, item_id: hir::HirId,
span: Span, span: Span,
sig_if_method: Option<&hir::MethodSig>, sig_if_method: Option<&hir::FnSig>,
) { ) {
debug!("check_associated_item: {:?}", item_id); debug!("check_associated_item: {:?}", item_id);
@ -783,7 +783,7 @@ const HELP_FOR_SELF_TYPE: &str =
fn check_method_receiver<'fcx, 'tcx>( fn check_method_receiver<'fcx, 'tcx>(
fcx: &FnCtxt<'fcx, 'tcx>, fcx: &FnCtxt<'fcx, 'tcx>,
method_sig: &hir::MethodSig, fn_sig: &hir::FnSig,
method: &ty::AssocItem, method: &ty::AssocItem,
self_ty: Ty<'tcx>, self_ty: Ty<'tcx>,
) { ) {
@ -794,7 +794,7 @@ fn check_method_receiver<'fcx, 'tcx>(
return; return;
} }
let span = method_sig.decl.inputs[0].span; let span = fn_sig.decl.inputs[0].span;
let sig = fcx.tcx.fn_sig(method.def_id); let sig = fcx.tcx.fn_sig(method.def_id);
let sig = fcx.normalize_associated_types_in(span, &sig); let sig = fcx.normalize_associated_types_in(span, &sig);

View File

@ -885,8 +885,8 @@ fn has_late_bound_regions<'tcx>(tcx: TyCtxt<'tcx>, node: Node<'tcx>) -> Option<S
_ => None, _ => None,
}, },
Node::Item(item) => match item.kind { Node::Item(item) => match item.kind {
hir::ItemKind::Fn(ref fn_decl, .., ref generics, _) => { hir::ItemKind::Fn(ref sig, .., ref generics, _) => {
has_late_bound_regions(tcx, generics, fn_decl) has_late_bound_regions(tcx, generics, &sig.decl)
} }
_ => None, _ => None,
}, },
@ -1779,17 +1779,17 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
match tcx.hir().get(hir_id) { match tcx.hir().get(hir_id) {
TraitItem(hir::TraitItem { TraitItem(hir::TraitItem {
kind: TraitItemKind::Method(MethodSig { header, decl }, TraitMethod::Provided(_)), kind: TraitItemKind::Method(sig, TraitMethod::Provided(_)),
.. ..
}) })
| ImplItem(hir::ImplItem { | ImplItem(hir::ImplItem {
kind: ImplItemKind::Method(MethodSig { header, decl }, _), kind: ImplItemKind::Method(sig, _),
.. ..
}) })
| Item(hir::Item { | Item(hir::Item {
kind: ItemKind::Fn(decl, header, _, _), kind: ItemKind::Fn(sig, _, _),
.. ..
}) => match get_infer_ret_ty(&decl.output) { }) => match get_infer_ret_ty(&sig.decl.output) {
Some(ty) => { Some(ty) => {
let fn_sig = tcx.typeck_tables_of(def_id).liberated_fn_sigs()[hir_id]; let fn_sig = tcx.typeck_tables_of(def_id).liberated_fn_sigs()[hir_id];
let mut diag = bad_placeholder_type(tcx, ty.span); let mut diag = bad_placeholder_type(tcx, ty.span);
@ -1805,11 +1805,11 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: DefId) -> ty::PolyFnSig<'_> {
diag.emit(); diag.emit();
ty::Binder::bind(fn_sig) ty::Binder::bind(fn_sig)
}, },
None => AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl) None => AstConv::ty_of_fn(&icx, sig.header.unsafety, sig.header.abi, &sig.decl)
}, },
TraitItem(hir::TraitItem { TraitItem(hir::TraitItem {
kind: TraitItemKind::Method(MethodSig { header, decl }, _), kind: TraitItemKind::Method(FnSig { header, decl }, _),
.. ..
}) => { }) => {
AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl) AstConv::ty_of_fn(&icx, header.unsafety, header.abi, decl)

View File

@ -1984,7 +1984,7 @@ pub struct Method {
pub ret_types: Vec<Type>, pub ret_types: Vec<Type>,
} }
impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId, impl<'a> Clean<Method> for (&'a hir::FnSig, &'a hir::Generics, hir::BodyId,
Option<hir::Defaultness>) { Option<hir::Defaultness>) {
fn clean(&self, cx: &DocContext<'_>) -> Method { fn clean(&self, cx: &DocContext<'_>) -> Method {
let (generics, decl) = enter_impl_trait(cx, || { let (generics, decl) = enter_impl_trait(cx, || {

View File

@ -438,8 +438,8 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
om.structs.push(self.visit_variant_data(item, ident.name, sd, gen)), om.structs.push(self.visit_variant_data(item, ident.name, sd, gen)),
hir::ItemKind::Union(ref sd, ref gen) => hir::ItemKind::Union(ref sd, ref gen) =>
om.unions.push(self.visit_union_data(item, ident.name, sd, gen)), om.unions.push(self.visit_union_data(item, ident.name, sd, gen)),
hir::ItemKind::Fn(ref fd, header, ref gen, body) => hir::ItemKind::Fn(ref sig, ref gen, body) =>
self.visit_fn(om, item, ident.name, &**fd, header, gen, body), self.visit_fn(om, item, ident.name, &sig.decl, sig.header, gen, body),
hir::ItemKind::TyAlias(ref ty, ref gen) => { hir::ItemKind::TyAlias(ref ty, ref gen) => {
let t = Typedef { let t = Typedef {
ty, ty,

View File

@ -1501,10 +1501,10 @@ pub struct MutTy {
pub mutbl: Mutability, pub mutbl: Mutability,
} }
/// Represents a method's signature in a trait declaration, /// Represents a function's signature in a trait declaration,
/// or in an implementation. /// trait implementation, or free function.
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct MethodSig { pub struct FnSig {
pub header: FnHeader, pub header: FnHeader,
pub decl: P<FnDecl>, pub decl: P<FnDecl>,
} }
@ -1528,7 +1528,7 @@ pub struct TraitItem {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum TraitItemKind { pub enum TraitItemKind {
Const(P<Ty>, Option<P<Expr>>), Const(P<Ty>, Option<P<Expr>>),
Method(MethodSig, Option<P<Block>>), Method(FnSig, Option<P<Block>>),
Type(GenericBounds, Option<P<Ty>>), Type(GenericBounds, Option<P<Ty>>),
Macro(Mac), Macro(Mac),
} }
@ -1552,7 +1552,7 @@ pub struct ImplItem {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum ImplItemKind { pub enum ImplItemKind {
Const(P<Ty>, P<Expr>), Const(P<Ty>, P<Expr>),
Method(MethodSig, P<Block>), Method(FnSig, P<Block>),
TyAlias(P<Ty>), TyAlias(P<Ty>),
OpaqueTy(GenericBounds), OpaqueTy(GenericBounds),
Macro(Mac), Macro(Mac),
@ -2433,7 +2433,7 @@ pub enum ItemKind {
/// A function declaration (`fn`). /// A function declaration (`fn`).
/// ///
/// E.g., `fn foo(bar: usize) -> usize { .. }`. /// E.g., `fn foo(bar: usize) -> usize { .. }`.
Fn(P<FnDecl>, FnHeader, Generics, P<Block>), Fn(FnSig, Generics, P<Block>),
/// A module declaration (`mod`). /// A module declaration (`mod`).
/// ///
/// E.g., `mod foo;` or `mod foo { .. }`. /// E.g., `mod foo;` or `mod foo { .. }`.

View File

@ -357,7 +357,7 @@ pub fn visit_bounds<T: MutVisitor>(bounds: &mut GenericBounds, vis: &mut T) {
} }
// No `noop_` prefix because there isn't a corresponding method in `MutVisitor`. // No `noop_` prefix because there isn't a corresponding method in `MutVisitor`.
pub fn visit_method_sig<T: MutVisitor>(MethodSig { header, decl }: &mut MethodSig, vis: &mut T) { pub fn visit_fn_sig<T: MutVisitor>(FnSig { header, decl }: &mut FnSig, vis: &mut T) {
vis.visit_fn_header(header); vis.visit_fn_header(header);
vis.visit_fn_decl(decl); vis.visit_fn_decl(decl);
} }
@ -878,9 +878,8 @@ pub fn noop_visit_item_kind<T: MutVisitor>(kind: &mut ItemKind, vis: &mut T) {
vis.visit_ty(ty); vis.visit_ty(ty);
vis.visit_expr(expr); vis.visit_expr(expr);
} }
ItemKind::Fn(decl, header, generics, body) => { ItemKind::Fn(sig, generics, body) => {
vis.visit_fn_decl(decl); visit_fn_sig(sig, vis);
vis.visit_fn_header(header);
vis.visit_generics(generics); vis.visit_generics(generics);
vis.visit_block(body); vis.visit_block(body);
} }
@ -938,7 +937,7 @@ pub fn noop_flat_map_trait_item<T: MutVisitor>(mut item: TraitItem, vis: &mut T)
visit_opt(default, |default| vis.visit_expr(default)); visit_opt(default, |default| vis.visit_expr(default));
} }
TraitItemKind::Method(sig, body) => { TraitItemKind::Method(sig, body) => {
visit_method_sig(sig, vis); visit_fn_sig(sig, vis);
visit_opt(body, |body| vis.visit_block(body)); visit_opt(body, |body| vis.visit_block(body));
} }
TraitItemKind::Type(bounds, default) => { TraitItemKind::Type(bounds, default) => {
@ -970,7 +969,7 @@ pub fn noop_flat_map_impl_item<T: MutVisitor>(mut item: ImplItem, visitor: &mut
visitor.visit_expr(expr); visitor.visit_expr(expr);
} }
ImplItemKind::Method(sig, body) => { ImplItemKind::Method(sig, body) => {
visit_method_sig(sig, visitor); visit_fn_sig(sig, visitor);
visitor.visit_block(body); visitor.visit_block(body);
} }
ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty), ImplItemKind::TyAlias(ty) => visitor.visit_ty(ty),

View File

@ -37,7 +37,7 @@ pub enum DirectoryOwnership {
relative: Option<ast::Ident>, relative: Option<ast::Ident>,
}, },
UnownedViaBlock, UnownedViaBlock,
UnownedViaMod(bool /* legacy warnings? */), UnownedViaMod,
} }
// A bunch of utility functions of the form `parse_<thing>_from_<source>` // A bunch of utility functions of the form `parse_<thing>_from_<source>`

View File

@ -287,7 +287,7 @@ impl<'a> Parser<'a> {
}; };
(format!("expected one of {}, found {}", expect, actual), (format!("expected one of {}, found {}", expect, actual),
(self.sess.source_map().next_point(self.prev_span), (self.sess.source_map().next_point(self.prev_span),
format!("expected one of {} here", short_expect))) format!("expected one of {}", short_expect)))
} else if expected.is_empty() { } else if expected.is_empty() {
(format!("unexpected token: {}", actual), (format!("unexpected token: {}", actual),
(self.prev_span, "unexpected token after this".to_string())) (self.prev_span, "unexpected token after this".to_string()))

View File

@ -8,7 +8,7 @@ use crate::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, Use
use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness}; use crate::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness};
use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind}; use crate::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
use crate::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField}; use crate::ast::{Ty, TyKind, Generics, GenericBounds, TraitRef, EnumDef, VariantData, StructField};
use crate::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, MethodSig, SelfKind, Param}; use crate::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
use crate::parse::token; use crate::parse::token;
use crate::tokenstream::{TokenTree, TokenStream}; use crate::tokenstream::{TokenTree, TokenStream};
use crate::symbol::{kw, sym}; use crate::symbol::{kw, sym};
@ -1800,7 +1800,7 @@ impl<'a> Parser<'a> {
is_name_required: |_| true, is_name_required: |_| true,
})?; })?;
let (inner_attrs, body) = self.parse_inner_attrs_and_block()?; let (inner_attrs, body) = self.parse_inner_attrs_and_block()?;
let kind = ItemKind::Fn(decl, header, generics, body); let kind = ItemKind::Fn(FnSig { decl, header }, generics, body);
self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs))) self.mk_item_with_info(attrs, lo, vis, (ident, kind, Some(inner_attrs)))
} }
@ -1897,14 +1897,14 @@ impl<'a> Parser<'a> {
fn parse_method_sig( fn parse_method_sig(
&mut self, &mut self,
is_name_required: fn(&token::Token) -> bool, is_name_required: fn(&token::Token) -> bool,
) -> PResult<'a, (Ident, MethodSig, Generics)> { ) -> PResult<'a, (Ident, FnSig, Generics)> {
let header = self.parse_fn_front_matter()?; let header = self.parse_fn_front_matter()?;
let (ident, decl, generics) = self.parse_fn_sig(ParamCfg { let (ident, decl, generics) = self.parse_fn_sig(ParamCfg {
is_self_allowed: true, is_self_allowed: true,
allow_c_variadic: false, allow_c_variadic: false,
is_name_required, is_name_required,
})?; })?;
Ok((ident, MethodSig { header, decl }, generics)) Ok((ident, FnSig { header, decl }, generics))
} }
/// Parses all the "front matter" for a `fn` declaration, up to /// Parses all the "front matter" for a `fn` declaration, up to

View File

@ -23,7 +23,6 @@ pub(super) struct ModulePath {
pub(super) struct ModulePathSuccess { pub(super) struct ModulePathSuccess {
pub path: PathBuf, pub path: PathBuf,
pub directory_ownership: DirectoryOwnership, pub directory_ownership: DirectoryOwnership,
warn: bool,
} }
impl<'a> Parser<'a> { impl<'a> Parser<'a> {
@ -57,17 +56,10 @@ impl<'a> Parser<'a> {
if self.eat(&token::Semi) { if self.eat(&token::Semi) {
if in_cfg && self.recurse_into_file_modules { if in_cfg && self.recurse_into_file_modules {
// This mod is in an external file. Let's go get it! // This mod is in an external file. Let's go get it!
let ModulePathSuccess { path, directory_ownership, warn } = let ModulePathSuccess { path, directory_ownership } =
self.submod_path(id, &outer_attrs, id_span)?; self.submod_path(id, &outer_attrs, id_span)?;
let (module, mut attrs) = let (module, attrs) =
self.eval_src_mod(path, directory_ownership, id.to_string(), id_span)?; 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 = attr::mk_attr_outer(
attr::mk_word_item(Ident::with_dummy_span(sym::warn_directory_ownership)));
attr::mark_known(&attr);
attrs.push(attr);
}
Ok((id, ItemKind::Mod(module), Some(attrs))) Ok((id, ItemKind::Mod(module), Some(attrs)))
} else { } else {
let placeholder = ast::Mod { let placeholder = ast::Mod {
@ -138,17 +130,16 @@ impl<'a> Parser<'a> {
// `#[path]` included and contains a `mod foo;` declaration. // `#[path]` included and contains a `mod foo;` declaration.
// If you encounter this, it's your own darn fault :P // If you encounter this, it's your own darn fault :P
Some(_) => DirectoryOwnership::Owned { relative: None }, Some(_) => DirectoryOwnership::Owned { relative: None },
_ => DirectoryOwnership::UnownedViaMod(true), _ => DirectoryOwnership::UnownedViaMod,
}, },
path, path,
warn: false,
}); });
} }
let relative = match self.directory.ownership { let relative = match self.directory.ownership {
DirectoryOwnership::Owned { relative } => relative, DirectoryOwnership::Owned { relative } => relative,
DirectoryOwnership::UnownedViaBlock | DirectoryOwnership::UnownedViaBlock |
DirectoryOwnership::UnownedViaMod(_) => None, DirectoryOwnership::UnownedViaMod => None,
}; };
let paths = Parser::default_submod_path( let paths = Parser::default_submod_path(
id, relative, &self.directory.path, self.sess.source_map()); id, relative, &self.directory.path, self.sess.source_map());
@ -169,12 +160,7 @@ impl<'a> Parser<'a> {
} }
Err(err) Err(err)
} }
DirectoryOwnership::UnownedViaMod(warn) => { DirectoryOwnership::UnownedViaMod => {
if warn {
if let Ok(result) = paths.result {
return Ok(ModulePathSuccess { warn: true, ..result });
}
}
let mut err = self.diagnostic().struct_span_err(id_sp, let mut err = self.diagnostic().struct_span_err(id_sp,
"cannot declare a new module at this location"); "cannot declare a new module at this location");
if !id_sp.is_dummy() { if !id_sp.is_dummy() {
@ -252,14 +238,12 @@ impl<'a> Parser<'a> {
directory_ownership: DirectoryOwnership::Owned { directory_ownership: DirectoryOwnership::Owned {
relative: Some(id), relative: Some(id),
}, },
warn: false,
}), }),
(false, true) => Ok(ModulePathSuccess { (false, true) => Ok(ModulePathSuccess {
path: secondary_path, path: secondary_path,
directory_ownership: DirectoryOwnership::Owned { directory_ownership: DirectoryOwnership::Owned {
relative: None, relative: None,
}, },
warn: false,
}), }),
(false, false) => Err(Error::FileNotFoundForModule { (false, false) => Err(Error::FileNotFoundForModule {
mod_name: mod_name.clone(), mod_name: mod_name.clone(),

View File

@ -1199,11 +1199,11 @@ impl<'a> State<'a> {
self.s.word(";"); self.s.word(";");
self.end(); // end the outer cbox self.end(); // end the outer cbox
} }
ast::ItemKind::Fn(ref decl, header, ref param_names, ref body) => { ast::ItemKind::Fn(ref sig, ref param_names, ref body) => {
self.head(""); self.head("");
self.print_fn( self.print_fn(
decl, &sig.decl,
header, sig.header,
Some(item.ident), Some(item.ident),
param_names, param_names,
&item.vis &item.vis
@ -1541,7 +1541,7 @@ impl<'a> State<'a> {
crate fn print_method_sig(&mut self, crate fn print_method_sig(&mut self,
ident: ast::Ident, ident: ast::Ident,
generics: &ast::Generics, generics: &ast::Generics,
m: &ast::MethodSig, m: &ast::FnSig,
vis: &ast::Visibility) vis: &ast::Visibility)
{ {
self.print_fn(&m.decl, self.print_fn(&m.decl,

View File

@ -25,7 +25,7 @@ pub enum FnKind<'a> {
ItemFn(Ident, &'a FnHeader, &'a Visibility, &'a Block), ItemFn(Ident, &'a FnHeader, &'a Visibility, &'a Block),
/// E.g., `fn foo(&self)`. /// E.g., `fn foo(&self)`.
Method(Ident, &'a MethodSig, Option<&'a Visibility>, &'a Block), Method(Ident, &'a FnSig, Option<&'a Visibility>, &'a Block),
/// E.g., `|x, y| body`. /// E.g., `|x, y| body`.
Closure(&'a Expr), Closure(&'a Expr),
@ -244,12 +244,11 @@ pub fn walk_item<'a, V: Visitor<'a>>(visitor: &mut V, item: &'a Item) {
visitor.visit_ty(typ); visitor.visit_ty(typ);
visitor.visit_expr(expr); visitor.visit_expr(expr);
} }
ItemKind::Fn(ref declaration, ref header, ref generics, ref body) => { ItemKind::Fn(ref sig, ref generics, ref body) => {
visitor.visit_generics(generics); visitor.visit_generics(generics);
visitor.visit_fn_header(header); visitor.visit_fn_header(&sig.header);
visitor.visit_fn(FnKind::ItemFn(item.ident, header, visitor.visit_fn(FnKind::ItemFn(item.ident, &sig.header, &item.vis, body),
&item.vis, body), &sig.decl,
declaration,
item.span, item.span,
item.id) item.id)
} }

View File

@ -1301,7 +1301,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> {
Some(_) => DirectoryOwnership::Owned { Some(_) => DirectoryOwnership::Owned {
relative: Some(item.ident), relative: Some(item.ident),
}, },
None => DirectoryOwnership::UnownedViaMod(false), None => DirectoryOwnership::UnownedViaMod,
}; };
path.pop(); path.pop();
module.directory = path; module.directory = path;

View File

@ -950,7 +950,7 @@ impl<'a> MethodDef<'a> {
let trait_lo_sp = trait_.span.shrink_to_lo(); let trait_lo_sp = trait_.span.shrink_to_lo();
let sig = ast::MethodSig { let sig = ast::FnSig {
header: ast::FnHeader { header: ast::FnHeader {
unsafety, unsafety,
abi: Abi::new(abi, trait_lo_sp), abi: Abi::new(abi, trait_lo_sp),

View File

@ -1,7 +1,7 @@
use crate::util::check_builtin_macro_attribute; use crate::util::check_builtin_macro_attribute;
use syntax::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafety}; use syntax::ast::{ItemKind, Mutability, Stmt, Ty, TyKind, Unsafety};
use syntax::ast::{self, Param, Attribute, Expr, FnHeader, Generics, Ident}; use syntax::ast::{self, Param, Attribute, Expr, FnSig, FnHeader, Generics, Ident};
use syntax::expand::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS}; use syntax::expand::allocator::{AllocatorKind, AllocatorMethod, AllocatorTy, ALLOCATOR_METHODS};
use syntax::ptr::P; use syntax::ptr::P;
use syntax::symbol::{kw, sym, Symbol}; use syntax::symbol::{kw, sym, Symbol};
@ -73,15 +73,10 @@ impl AllocFnFactory<'_, '_> {
.collect(); .collect();
let result = self.call_allocator(method.name, args); let result = self.call_allocator(method.name, args);
let (output_ty, output_expr) = self.ret_ty(&method.output, result); let (output_ty, output_expr) = self.ret_ty(&method.output, result);
let kind = ItemKind::Fn( let decl = self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty));
self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)), let header = FnHeader { unsafety: Unsafety::Unsafe, ..FnHeader::default() };
FnHeader { let sig = FnSig { decl, header };
unsafety: Unsafety::Unsafe, let kind = ItemKind::Fn(sig, Generics::default(), self.cx.block_expr(output_expr));
..FnHeader::default()
},
Generics::default(),
self.cx.block_expr(output_expr),
);
let item = self.cx.item( let item = self.cx.item(
self.span, self.span,
self.cx.ident_of(&self.kind.fn_name(method.name), self.span), self.cx.ident_of(&self.kind.fn_name(method.name), self.span),

View File

@ -310,15 +310,15 @@ fn test_type(cx: &ExtCtxt<'_>) -> TestType {
fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic); let has_should_panic_attr = attr::contains_name(&i.attrs, sym::should_panic);
let ref sd = cx.parse_sess.span_diagnostic; let ref sd = cx.parse_sess.span_diagnostic;
if let ast::ItemKind::Fn(ref decl, ref header, ref generics, _) = i.kind { if let ast::ItemKind::Fn(ref sig, ref generics, _) = i.kind {
if header.unsafety == ast::Unsafety::Unsafe { if sig.header.unsafety == ast::Unsafety::Unsafe {
sd.span_err( sd.span_err(
i.span, i.span,
"unsafe functions cannot be used for tests" "unsafe functions cannot be used for tests"
); );
return false return false
} }
if header.asyncness.node.is_async() { if sig.header.asyncness.node.is_async() {
sd.span_err( sd.span_err(
i.span, i.span,
"async functions cannot be used for tests" "async functions cannot be used for tests"
@ -329,13 +329,13 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
// If the termination trait is active, the compiler will check that the output // If the termination trait is active, the compiler will check that the output
// type implements the `Termination` trait as `libtest` enforces that. // type implements the `Termination` trait as `libtest` enforces that.
let has_output = match decl.output { let has_output = match sig.decl.output {
ast::FunctionRetTy::Default(..) => false, ast::FunctionRetTy::Default(..) => false,
ast::FunctionRetTy::Ty(ref t) if t.kind.is_unit() => false, ast::FunctionRetTy::Ty(ref t) if t.kind.is_unit() => false,
_ => true _ => true
}; };
if !decl.inputs.is_empty() { if !sig.decl.inputs.is_empty() {
sd.span_err(i.span, "functions used as tests can not have any arguments"); sd.span_err(i.span, "functions used as tests can not have any arguments");
return false; return false;
} }
@ -361,10 +361,10 @@ fn has_test_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
} }
fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool { fn has_bench_signature(cx: &ExtCtxt<'_>, i: &ast::Item) -> bool {
let has_sig = if let ast::ItemKind::Fn(ref decl, _, _, _) = i.kind { let has_sig = if let ast::ItemKind::Fn(ref sig, _, _) = i.kind {
// N.B., inadequate check, but we're running // N.B., inadequate check, but we're running
// well before resolve, can't get too deep. // well before resolve, can't get too deep.
decl.inputs.len() == 1 sig.decl.inputs.len() == 1
} else { } else {
false false
}; };

View File

@ -306,10 +306,9 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
ecx.block(sp, vec![call_test_main]) ecx.block(sp, vec![call_test_main])
}; };
let main = ast::ItemKind::Fn(ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)), let decl = ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty));
ast::FnHeader::default(), let sig = ast::FnSig { decl, header: ast::FnHeader::default() };
ast::Generics::default(), let main = ast::ItemKind::Fn(sig, ast::Generics::default(), main_body);
main_body);
// Honor the reexport_test_harness_main attribute // Honor the reexport_test_harness_main attribute
let main_id = match cx.reexport_test_harness_main { let main_id = match cx.reexport_test_harness_main {

View File

@ -739,7 +739,6 @@ symbols! {
visible_private_types, visible_private_types,
volatile, volatile,
warn, warn,
warn_directory_ownership,
wasm_import_module, wasm_import_module,
wasm_target_feature, wasm_target_feature,
while_let, while_let,

View File

@ -2,7 +2,7 @@ error: expected one of `:`, `@`, or `|`, found `)`
--> $DIR/anon-params-denied-2018.rs:6:15 --> $DIR/anon-params-denied-2018.rs:6:15
| |
LL | fn foo(i32); LL | fn foo(i32);
| ^ expected one of `:`, `@`, or `|` here | ^ expected one of `:`, `@`, or `|`
| |
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685) = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
help: if this is a `self` type, give it a parameter name help: if this is a `self` type, give it a parameter name
@ -22,7 +22,7 @@ error: expected one of `:`, `@`, or `|`, found `,`
--> $DIR/anon-params-denied-2018.rs:8:36 --> $DIR/anon-params-denied-2018.rs:8:36
| |
LL | fn bar_with_default_impl(String, String) {} LL | fn bar_with_default_impl(String, String) {}
| ^ expected one of `:`, `@`, or `|` here | ^ expected one of `:`, `@`, or `|`
| |
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685) = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
help: if this is a `self` type, give it a parameter name help: if this is a `self` type, give it a parameter name
@ -42,7 +42,7 @@ error: expected one of `:`, `@`, or `|`, found `)`
--> $DIR/anon-params-denied-2018.rs:8:44 --> $DIR/anon-params-denied-2018.rs:8:44
| |
LL | fn bar_with_default_impl(String, String) {} LL | fn bar_with_default_impl(String, String) {}
| ^ expected one of `:`, `@`, or `|` here | ^ expected one of `:`, `@`, or `|`
| |
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685) = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
help: if this was a parameter name, give it a type help: if this was a parameter name, give it a type
@ -58,7 +58,7 @@ error: expected one of `:`, `@`, or `|`, found `,`
--> $DIR/anon-params-denied-2018.rs:13:22 --> $DIR/anon-params-denied-2018.rs:13:22
| |
LL | fn baz(a:usize, b, c: usize) -> usize { LL | fn baz(a:usize, b, c: usize) -> usize {
| ^ expected one of `:`, `@`, or `|` here | ^ expected one of `:`, `@`, or `|`
| |
= note: anonymous parameters are removed in the 2018 edition (see RFC 1685) = note: anonymous parameters are removed in the 2018 edition (see RFC 1685)
help: if this was a parameter name, give it a type help: if this was a parameter name, give it a type

View File

@ -130,7 +130,7 @@ error: expected one of `.`, `?`, `{`, or an operator, found `}`
--> $DIR/incorrect-syntax-suggestions.rs:134:1 --> $DIR/incorrect-syntax-suggestions.rs:134:1
| |
LL | match await { await => () } LL | match await { await => () }
| ----- - expected one of `.`, `?`, `{`, or an operator here | ----- - expected one of `.`, `?`, `{`, or an operator
| | | |
| while parsing this match expression | while parsing this match expression
... ...

View File

@ -2,7 +2,7 @@ error: expected one of `fn` or `unsafe`, found keyword `const`
--> $DIR/no-async-const.rs:5:11 --> $DIR/no-async-const.rs:5:11
| |
LL | pub async const fn x() {} LL | pub async const fn x() {}
| ^^^^^ expected one of `fn` or `unsafe` here | ^^^^^ expected one of `fn` or `unsafe`
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,13 +2,13 @@ error: expected one of `extern` or `fn`, found keyword `async`
--> $DIR/no-unsafe-async.rs:7:12 --> $DIR/no-unsafe-async.rs:7:12
| |
LL | unsafe async fn g() {} LL | unsafe async fn g() {}
| ^^^^^ expected one of `extern` or `fn` here | ^^^^^ expected one of `extern` or `fn`
error: expected one of `extern`, `fn`, or `{`, found keyword `async` error: expected one of `extern`, `fn`, or `{`, found keyword `async`
--> $DIR/no-unsafe-async.rs:11:8 --> $DIR/no-unsafe-async.rs:11:8
| |
LL | unsafe async fn f() {} LL | unsafe async fn f() {}
| ^^^^^ expected one of `extern`, `fn`, or `{` here | ^^^^^ expected one of `extern`, `fn`, or `{`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -2,7 +2,7 @@ error: expected one of `.`, `;`, `?`, `}`, or an operator, found keyword `enum`
--> $DIR/can-begin-expr-check.rs:19:12 --> $DIR/can-begin-expr-check.rs:19:12
| |
LL | return enum; LL | return enum;
| ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator here | ^^^^ expected one of `.`, `;`, `?`, `}`, or an operator
error: aborting due to previous error error: aborting due to previous error

View File

@ -16,7 +16,7 @@ error: expected one of `,`, `.`, `?`, or an operator, found `1`
--> $DIR/bad-format-args.rs:4:19 --> $DIR/bad-format-args.rs:4:19
| |
LL | format!("", 1 1); LL | format!("", 1 1);
| ^ expected one of `,`, `.`, `?`, or an operator here | ^ expected one of `,`, `.`, `?`, or an operator
error: aborting due to 3 previous errors error: aborting due to 3 previous errors

View File

@ -2,7 +2,7 @@ error: expected one of `,` or `>`, found `+`
--> $DIR/const-expression-parameter.rs:13:22 --> $DIR/const-expression-parameter.rs:13:22
| |
LL | i32_identity::<1 + 2>(); LL | i32_identity::<1 + 2>();
| ^ expected one of `,` or `>` here | ^ expected one of `,` or `>`
warning: the feature `const_generics` is incomplete and may cause the compiler to crash warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/const-expression-parameter.rs:1:12 --> $DIR/const-expression-parameter.rs:1:12

View File

@ -48,7 +48,7 @@ error: expected one of `!` or `::`, found `(`
--> $DIR/issue-40006.rs:28:9 --> $DIR/issue-40006.rs:28:9
| |
LL | ::Y (); LL | ::Y ();
| ^ expected one of `!` or `::` here | ^ expected one of `!` or `::`
error: missing `fn`, `type`, or `const` for impl-item declaration error: missing `fn`, `type`, or `const` for impl-item declaration
--> $DIR/issue-40006.rs:32:8 --> $DIR/issue-40006.rs:32:8

View File

@ -24,7 +24,7 @@ error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found
LL | if (a and b) { LL | if (a and b) {
| ^^^ | ^^^
| | | |
| expected one of 8 possible tokens here | expected one of 8 possible tokens
| help: use `&&` instead of `and` for the boolean operator | help: use `&&` instead of `and` for the boolean operator
error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or` error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found `or`
@ -33,7 +33,7 @@ error: expected one of `!`, `)`, `,`, `.`, `::`, `?`, `{`, or an operator, found
LL | if (a or b) { LL | if (a or b) {
| ^^ | ^^
| | | |
| expected one of 8 possible tokens here | expected one of 8 possible tokens
| help: use `||` instead of `or` for the boolean operator | help: use `||` instead of `or` for the boolean operator
error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and` error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and`
@ -42,7 +42,7 @@ error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `and`
LL | while a and b { LL | while a and b {
| ^^^ | ^^^
| | | |
| expected one of `!`, `.`, `::`, `?`, `{`, or an operator here | expected one of `!`, `.`, `::`, `?`, `{`, or an operator
| help: use `&&` instead of `and` for the boolean operator | help: use `&&` instead of `and` for the boolean operator
error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or` error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or`
@ -51,7 +51,7 @@ error: expected one of `!`, `.`, `::`, `?`, `{`, or an operator, found `or`
LL | while a or b { LL | while a or b {
| ^^ | ^^
| | | |
| expected one of `!`, `.`, `::`, `?`, `{`, or an operator here | expected one of `!`, `.`, `::`, `?`, `{`, or an operator
| help: use `||` instead of `or` for the boolean operator | help: use `||` instead of `or` for the boolean operator
error: aborting due to 6 previous errors error: aborting due to 6 previous errors

View File

@ -36,7 +36,7 @@ error: macro expansion ends with an incomplete expression: expected one of `move
--> <::edition_kw_macro_2015::passes_ident macros>:1:22 --> <::edition_kw_macro_2015::passes_ident macros>:1:22
| |
LL | ($ i : ident) => ($ i) LL | ($ i : ident) => ($ i)
| ^ expected one of `move`, `|`, or `||` here | ^ expected one of `move`, `|`, or `||`
| |
::: $DIR/edition-keywords-2018-2015-parsing.rs:16:8 ::: $DIR/edition-keywords-2018-2015-parsing.rs:16:8
| |

View File

@ -36,7 +36,7 @@ error: macro expansion ends with an incomplete expression: expected one of `move
--> <::edition_kw_macro_2018::passes_ident macros>:1:22 --> <::edition_kw_macro_2018::passes_ident macros>:1:22
| |
LL | ($ i : ident) => ($ i) LL | ($ i : ident) => ($ i)
| ^ expected one of `move`, `|`, or `||` here | ^ expected one of `move`, `|`, or `||`
| |
::: $DIR/edition-keywords-2018-2018-parsing.rs:16:8 ::: $DIR/edition-keywords-2018-2018-parsing.rs:16:8
| |

View File

@ -15,7 +15,7 @@ mod inline {
//~^ ERROR attribute should be applied to function or closure //~^ ERROR attribute should be applied to function or closure
#[inline = "2100"] fn f() { } #[inline = "2100"] fn f() { }
//~^ WARN attribute must be of the form //~^ ERROR attribute must be of the form
//~| WARN this was previously accepted //~| WARN this was previously accepted
#[inline] struct S; #[inline] struct S;

View File

@ -1,10 +1,10 @@
warning: attribute must be of the form `#[inline]` or `#[inline(always|never)]` error: attribute must be of the form `#[inline]` or `#[inline(always|never)]`
--> $DIR/issue-43106-gating-of-inline.rs:17:5 --> $DIR/issue-43106-gating-of-inline.rs:17:5
| |
LL | #[inline = "2100"] fn f() { } LL | #[inline = "2100"] fn f() { }
| ^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^
| |
= note: `#[warn(ill_formed_attribute_input)]` on by default = note: `#[deny(ill_formed_attribute_input)]` on by default
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571> = note: for more information, see issue #57571 <https://github.com/rust-lang/rust/issues/57571>
@ -47,6 +47,6 @@ error[E0518]: attribute should be applied to function or closure
LL | #[inline] impl S { } LL | #[inline] impl S { }
| ^^^^^^^^^ ---------- not a function or closure | ^^^^^^^^^ ---------- not a function or closure
error: aborting due to 5 previous errors error: aborting due to 6 previous errors
For more information about this error, try `rustc --explain E0518`. For more information about this error, try `rustc --explain E0518`.

View File

@ -2,7 +2,7 @@ error: expected one of `!` or `::`, found `-`
--> $DIR/feature-gate-extern_prelude.rs:1:4 --> $DIR/feature-gate-extern_prelude.rs:1:4
| |
LL | can-only-test-this-in-run-make-fulldeps LL | can-only-test-this-in-run-make-fulldeps
| ^ expected one of `!` or `::` here | ^ expected one of `!` or `::`
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,42 +1,17 @@
// rust-lang/rust#57979 : the initial support for `impl Trait` didn't // rust-lang/rust#57979 : the initial support for `impl Trait` didn't
// properly check syntax hidden behind an associated type projection, // properly check syntax hidden behind an associated type projection,
// but it did catch *some cases*. This is checking that we continue to // but it did catch *some cases*. This is checking that we continue to
// properly emit errors for those, even with the new // properly emit errors for those.
// future-incompatibility warnings.
// //
// issue-57979-nested-impl-trait-in-assoc-proj.rs shows the main case // issue-57979-nested-impl-trait-in-assoc-proj.rs shows the main case
// that we were previously failing to catch. // that we were previously failing to catch.
struct Deeper<T>(T); struct Deeper<T>(T);
mod allowed {
#![allow(nested_impl_trait)]
pub trait Foo<T> { } pub trait Foo<T> { }
pub trait Bar { } pub trait Bar { }
pub trait Quux { type Assoc; } pub trait Quux { type Assoc; }
pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { } pub fn demo(_: impl Quux<Assoc=Deeper<impl Foo<impl Bar>>>) { }
//~^ ERROR nested `impl Trait` is not allowed //~^ ERROR nested `impl Trait` is not allowed
}
mod warned {
#![warn(nested_impl_trait)]
pub trait Foo<T> { }
pub trait Bar { }
pub trait Quux { type Assoc; }
pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
//~^ ERROR nested `impl Trait` is not allowed
}
mod denied {
#![deny(nested_impl_trait)]
pub trait Foo<T> { }
pub trait Bar { }
pub trait Quux { type Assoc; }
pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
//~^ ERROR nested `impl Trait` is not allowed
}
fn main() { } fn main() { }

View File

@ -1,30 +1,12 @@
error[E0666]: nested `impl Trait` is not allowed error[E0666]: nested `impl Trait` is not allowed
--> $DIR/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs:18:59 --> $DIR/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs:14:48
| |
LL | pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { } LL | pub fn demo(_: impl Quux<Assoc=Deeper<impl Foo<impl Bar>>>) { }
| ---------^^^^^^^^- | ---------^^^^^^^^-
| | | | | |
| | nested `impl Trait` here | | nested `impl Trait` here
| outer `impl Trait` | outer `impl Trait`
error[E0666]: nested `impl Trait` is not allowed error: aborting due to previous error
--> $DIR/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs:28:59
|
LL | pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
| ---------^^^^^^^^-
| | |
| | nested `impl Trait` here
| outer `impl Trait`
error[E0666]: nested `impl Trait` is not allowed
--> $DIR/issue-57979-deeply-nested-impl-trait-in-assoc-proj.rs:38:59
|
LL | pub fn demo(_: impl Quux<Assoc=super::Deeper<impl Foo<impl Bar>>>) { }
| ---------^^^^^^^^-
| | |
| | nested `impl Trait` here
| outer `impl Trait`
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0666`. For more information about this error, try `rustc --explain E0666`.

View File

@ -3,35 +3,10 @@
// Here we test behavior of occurrences of `impl Trait` within a path // Here we test behavior of occurrences of `impl Trait` within a path
// component in that context. // component in that context.
mod allowed {
#![allow(nested_impl_trait)]
pub trait Bar { }
pub trait Quux<T> { type Assoc; }
pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
impl<T> Quux<T> for () { type Assoc = u32; }
}
mod warned {
#![warn(nested_impl_trait)]
pub trait Bar { }
pub trait Quux<T> { type Assoc; }
pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
//~^ WARN `impl Trait` is not allowed in path parameters
//~| WARN will become a hard error in a future release!
impl<T> Quux<T> for () { type Assoc = u32; }
}
mod denied {
#![deny(nested_impl_trait)]
pub trait Bar { } pub trait Bar { }
pub trait Quux<T> { type Assoc; } pub trait Quux<T> { type Assoc; }
pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { } pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
//~^ ERROR `impl Trait` is not allowed in path parameters //~^ ERROR `impl Trait` is not allowed in path parameters
//~| WARN will become a hard error in a future release!
impl<T> Quux<T> for () { type Assoc = u32; } impl<T> Quux<T> for () { type Assoc = u32; }
}
fn main() { } fn main() { }

View File

@ -1,30 +1,8 @@
warning: `impl Trait` is not allowed in path parameters error[E0667]: `impl Trait` is not allowed in path parameters
--> $DIR/issue-57979-impl-trait-in-path.rs:20:52 --> $DIR/issue-57979-impl-trait-in-path.rs:8:48
| |
LL | pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { } LL | pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
| ^^^^^^^^ | ^^^^^^^^
|
note: lint level defined here
--> $DIR/issue-57979-impl-trait-in-path.rs:16:13
|
LL | #![warn(nested_impl_trait)]
| ^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #59014 <https://github.com/rust-lang/rust/issues/59014>
error: `impl Trait` is not allowed in path parameters
--> $DIR/issue-57979-impl-trait-in-path.rs:31:52
|
LL | pub fn demo(_: impl Quux<(), Assoc=<() as Quux<impl Bar>>::Assoc>) { }
| ^^^^^^^^
|
note: lint level defined here
--> $DIR/issue-57979-impl-trait-in-path.rs:27:13
|
LL | #![deny(nested_impl_trait)]
| ^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #59014 <https://github.com/rust-lang/rust/issues/59014>
error: aborting due to previous error error: aborting due to previous error

View File

@ -3,35 +3,10 @@
// Here we test behavior of occurrences of `impl Trait` within an // Here we test behavior of occurrences of `impl Trait` within an
// `impl Trait` in that context. // `impl Trait` in that context.
mod allowed {
#![allow(nested_impl_trait)]
pub trait Foo<T> { }
pub trait Bar { }
pub trait Quux { type Assoc; }
pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
}
mod warned {
#![warn(nested_impl_trait)]
pub trait Foo<T> { }
pub trait Bar { }
pub trait Quux { type Assoc; }
pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
//~^ WARN nested `impl Trait` is not allowed
//~| WARN will become a hard error in a future release!
}
mod denied {
#![deny(nested_impl_trait)]
pub trait Foo<T> { } pub trait Foo<T> { }
pub trait Bar { } pub trait Bar { }
pub trait Quux { type Assoc; } pub trait Quux { type Assoc; }
pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { } pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
//~^ ERROR nested `impl Trait` is not allowed //~^ ERROR nested `impl Trait` is not allowed
//~| WARN will become a hard error in a future release!
}
fn main() { } fn main() { }

View File

@ -1,36 +1,12 @@
warning: nested `impl Trait` is not allowed error[E0666]: nested `impl Trait` is not allowed
--> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:21:45 --> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:9:41
| |
LL | pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { } LL | pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
| ---------^^^^^^^^- | ---------^^^^^^^^-
| | | | | |
| | nested `impl Trait` here | | nested `impl Trait` here
| outer `impl Trait` | outer `impl Trait`
|
note: lint level defined here
--> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:16:13
|
LL | #![warn(nested_impl_trait)]
| ^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #59014 <https://github.com/rust-lang/rust/issues/59014>
error: nested `impl Trait` is not allowed
--> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:32:45
|
LL | pub fn demo(_: impl Quux<Assoc=impl Foo<impl Bar>>) { }
| ---------^^^^^^^^-
| | |
| | nested `impl Trait` here
| outer `impl Trait`
|
note: lint level defined here
--> $DIR/issue-57979-nested-impl-trait-in-assoc-proj.rs:27:13
|
LL | #![deny(nested_impl_trait)]
| ^^^^^^^^^^^^^^^^^
= warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release!
= note: for more information, see issue #59014 <https://github.com/rust-lang/rust/issues/59014>
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0666`.

View File

@ -2,7 +2,7 @@ error: expected one of `::`, `;`, or `as`, found `{`
--> $DIR/import-prefix-macro-1.rs:11:27 --> $DIR/import-prefix-macro-1.rs:11:27
| |
LL | ($p: path) => (use $p {S, Z}); LL | ($p: path) => (use $p {S, Z});
| ^^^^^^ expected one of `::`, `;`, or `as` here | ^^^^^^ expected one of `::`, `;`, or `as`
... ...
LL | import! { a::b::c } LL | import! { a::b::c }
| ------------------- in this macro invocation | ------------------- in this macro invocation

View File

@ -8,7 +8,7 @@ error: expected one of `->`, `where`, or `{`, found `;`
--> $DIR/invalid-variadic-function.rs:1:30 --> $DIR/invalid-variadic-function.rs:1:30
| |
LL | extern "C" fn foo(x: u8, ...); LL | extern "C" fn foo(x: u8, ...);
| ^ expected one of `->`, `where`, or `{` here | ^ expected one of `->`, `where`, or `{`
error: aborting due to 2 previous errors error: aborting due to 2 previous errors

View File

@ -1,7 +0,0 @@
#![allow(duplicate_macro_exports)]
#[macro_export]
macro_rules! foo_modern { ($i:ident) => {} }
#[macro_export]
macro_rules! foo_modern { () => {} }

View File

@ -1,7 +0,0 @@
#![allow(duplicate_macro_exports)]
#[macro_export]
macro_rules! foo { ($i:ident) => {} }
#[macro_export]
macro_rules! foo { () => {} }

View File

@ -1,10 +1,7 @@
#![allow(safe_extern_statics, warnings)]
extern { extern {
pub static symbol: u32; pub static symbol: u32;
} }
static CRASH: u32 = symbol; static CRASH: u32 = symbol;
//~^ ERROR could not evaluate static initializer //~^ ERROR use of extern static is unsafe and requires
//~| tried to read from foreign (extern) static
fn main() {} fn main() {}

View File

@ -1,9 +1,11 @@
error[E0080]: could not evaluate static initializer error[E0133]: use of extern static is unsafe and requires unsafe function or block
--> $DIR/issue-14227.rs:6:21 --> $DIR/issue-14227.rs:4:21
| |
LL | static CRASH: u32 = symbol; LL | static CRASH: u32 = symbol;
| ^^^^^^ tried to read from foreign (extern) static | ^^^^^^ use of extern static
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`. For more information about this error, try `rustc --explain E0133`.

View File

@ -1,5 +1,3 @@
#![allow(safe_extern_statics)]
mod Y { mod Y {
pub type X = usize; pub type X = usize;
extern { extern {
@ -13,5 +11,6 @@ mod Y {
static foo: *const Y::X = Y::foo(Y::x as *const Y::X); static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
//~^ ERROR `*const usize` cannot be shared between threads safely [E0277] //~^ ERROR `*const usize` cannot be shared between threads safely [E0277]
//~| ERROR E0015 //~| ERROR E0015
//~| ERROR use of extern static is unsafe and requires
fn main() {} fn main() {}

View File

@ -1,11 +1,11 @@
error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants error[E0015]: calls in statics are limited to constant functions, tuple structs and tuple variants
--> $DIR/issue-16538.rs:13:27 --> $DIR/issue-16538.rs:11:27
| |
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X); LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ^^^^^^^^^^^^^^^^^^^^^^^^^^^
error[E0277]: `*const usize` cannot be shared between threads safely error[E0277]: `*const usize` cannot be shared between threads safely
--> $DIR/issue-16538.rs:13:1 --> $DIR/issue-16538.rs:11:1
| |
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X); LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const usize` cannot be shared between threads safely | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ `*const usize` cannot be shared between threads safely
@ -13,7 +13,15 @@ LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
= help: the trait `std::marker::Sync` is not implemented for `*const usize` = help: the trait `std::marker::Sync` is not implemented for `*const usize`
= note: shared static variables must have a type that implements `Sync` = note: shared static variables must have a type that implements `Sync`
error: aborting due to 2 previous errors error[E0133]: use of extern static is unsafe and requires unsafe function or block
--> $DIR/issue-16538.rs:11:34
|
LL | static foo: *const Y::X = Y::foo(Y::x as *const Y::X);
| ^^^^ use of extern static
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
Some errors have detailed explanations: E0015, E0277. error: aborting due to 3 previous errors
Some errors have detailed explanations: E0015, E0133, E0277.
For more information about an error, try `rustc --explain E0015`. For more information about an error, try `rustc --explain E0015`.

View File

@ -2,7 +2,7 @@ error: expected one of `,`, `:`, or `>`, found `T`
--> $DIR/issue-20616-1.rs:9:16 --> $DIR/issue-20616-1.rs:9:16
| |
LL | type Type_1<'a T> = &'a T; LL | type Type_1<'a T> = &'a T;
| ^ expected one of `,`, `:`, or `>` here | ^ expected one of `,`, `:`, or `>`
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error: expected one of `,` or `>`, found `(`
--> $DIR/issue-20616-2.rs:12:31 --> $DIR/issue-20616-2.rs:12:31
| |
LL | type Type_2 = Type_1_<'static ()>; LL | type Type_2 = Type_1_<'static ()>;
| ^ expected one of `,` or `>` here | ^ expected one of `,` or `>`
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
--> $DIR/issue-20616-3.rs:13:24 --> $DIR/issue-20616-3.rs:13:24
| |
LL | type Type_3<T> = Box<T,,>; LL | type Type_3<T> = Box<T,,>;
| ^ expected one of `>`, const, identifier, lifetime, or type here | ^ expected one of `>`, const, identifier, lifetime, or type
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
--> $DIR/issue-20616-4.rs:16:34 --> $DIR/issue-20616-4.rs:16:34
| |
LL | type Type_4<T> = Type_1_<'static,, T>; LL | type Type_4<T> = Type_1_<'static,, T>;
| ^ expected one of `>`, const, identifier, lifetime, or type here | ^ expected one of `>`, const, identifier, lifetime, or type
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
--> $DIR/issue-20616-5.rs:22:34 --> $DIR/issue-20616-5.rs:22:34
| |
LL | type Type_5<'a> = Type_1_<'a, (),,>; LL | type Type_5<'a> = Type_1_<'a, (),,>;
| ^ expected one of `>`, const, identifier, lifetime, or type here | ^ expected one of `>`, const, identifier, lifetime, or type
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
--> $DIR/issue-20616-6.rs:25:26 --> $DIR/issue-20616-6.rs:25:26
| |
LL | type Type_6 = Type_5_<'a,,>; LL | type Type_6 = Type_5_<'a,,>;
| ^ expected one of `>`, const, identifier, lifetime, or type here | ^ expected one of `>`, const, identifier, lifetime, or type
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error: expected one of `>`, const, identifier, lifetime, or type, found `,`
--> $DIR/issue-20616-7.rs:28:22 --> $DIR/issue-20616-7.rs:28:22
| |
LL | type Type_7 = Box<(),,>; LL | type Type_7 = Box<(),,>;
| ^ expected one of `>`, const, identifier, lifetime, or type here | ^ expected one of `>`, const, identifier, lifetime, or type
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error: expected one of `>`, `const`, identifier, or lifetime, found `,`
--> $DIR/issue-20616-8.rs:31:16 --> $DIR/issue-20616-8.rs:31:16
| |
LL | type Type_8<'a,,> = &'a (); LL | type Type_8<'a,,> = &'a ();
| ^ expected one of `>`, `const`, identifier, or lifetime here | ^ expected one of `>`, `const`, identifier, or lifetime
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error: expected one of `>`, `const`, identifier, or lifetime, found `,`
--> $DIR/issue-20616-9.rs:34:15 --> $DIR/issue-20616-9.rs:34:15
| |
LL | type Type_9<T,,> = Box<T>; LL | type Type_9<T,,> = Box<T>;
| ^ expected one of `>`, `const`, identifier, or lifetime here | ^ expected one of `>`, `const`, identifier, or lifetime
error: aborting due to previous error error: aborting due to previous error

View File

@ -2,7 +2,7 @@ error: expected one of `!` or `::`, found `<eof>`
--> $DIR/auxiliary/issue-21146-inc.rs:3:1 --> $DIR/auxiliary/issue-21146-inc.rs:3:1
| |
LL | parse_error LL | parse_error
| ^^^^^^^^^^^ expected one of `!` or `::` here | ^^^^^^^^^^^ expected one of `!` or `::`
error: aborting due to previous error error: aborting due to previous error

View File

@ -1,11 +1,8 @@
#![allow(safe_extern_statics)]
extern { extern {
static error_message_count: u32; static error_message_count: u32;
} }
pub static BAZ: u32 = *&error_message_count; pub static BAZ: u32 = *&error_message_count;
//~^ ERROR could not evaluate static initializer //~^ ERROR use of extern static is unsafe and requires
//~| tried to read from foreign (extern) static
fn main() {} fn main() {}

View File

@ -1,9 +1,11 @@
error[E0080]: could not evaluate static initializer error[E0133]: use of extern static is unsafe and requires unsafe function or block
--> $DIR/issue-28324.rs:7:23 --> $DIR/issue-28324.rs:5:24
| |
LL | pub static BAZ: u32 = *&error_message_count; LL | pub static BAZ: u32 = *&error_message_count;
| ^^^^^^^^^^^^^^^^^^^^^ tried to read from foreign (extern) static | ^^^^^^^^^^^^^^^^^^^^ use of extern static
|
= note: extern statics are not controlled by the Rust type system: invalid data, aliasing violations or data races will cause undefined behavior
error: aborting due to previous error error: aborting due to previous error
For more information about this error, try `rustc --explain E0080`. For more information about this error, try `rustc --explain E0133`.

Some files were not shown because too many files have changed in this diff Show More