Auto merge of #69226 - JohnTitor:rollup-syn03oj, r=JohnTitor

Rollup of 6 pull requests

Successful merges:

 - #68495 (Updating str.chars docs to mention crates.io.)
 - #68701 (Improve #Safety of various methods in core::ptr)
 - #69158 (Don't print block exit state in dataflow graphviz if unchanged)
 - #69179 (Rename `FunctionRetTy` to `FnRetTy`)
 - #69186 ([tiny] parser: `macro_rules` is a weak keyword)
 - #69188 (Clean up E0309 explanation)

Failed merges:

r? @ghost
This commit is contained in:
bors 2020-02-17 06:44:35 +00:00
commit 75b98fbe77
50 changed files with 184 additions and 157 deletions

View File

@ -119,10 +119,13 @@ mod mut_ptr;
/// ///
/// Behavior is undefined if any of the following conditions are violated: /// Behavior is undefined if any of the following conditions are violated:
/// ///
/// * `to_drop` must be [valid] for reads. /// * `to_drop` must be [valid] for both reads and writes.
/// ///
/// * `to_drop` must be properly aligned. /// * `to_drop` must be properly aligned.
/// ///
/// * The value `to_drop` points to must be valid for dropping, which may mean it must uphold
/// additional invariants - this is type-dependent.
///
/// Additionally, if `T` is not [`Copy`], using the pointed-to value after /// Additionally, if `T` is not [`Copy`], using the pointed-to value after
/// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop = /// calling `drop_in_place` can cause undefined behavior. Note that `*to_drop =
/// foo` counts as a use because it will cause the value to be dropped /// foo` counts as a use because it will cause the value to be dropped
@ -289,7 +292,7 @@ pub const fn slice_from_raw_parts_mut<T>(data: *mut T, len: usize) -> *mut [T] {
/// ///
/// Behavior is undefined if any of the following conditions are violated: /// Behavior is undefined if any of the following conditions are violated:
/// ///
/// * Both `x` and `y` must be [valid] for reads and writes. /// * Both `x` and `y` must be [valid] for both reads and writes.
/// ///
/// * Both `x` and `y` must be properly aligned. /// * Both `x` and `y` must be properly aligned.
/// ///
@ -355,7 +358,7 @@ pub unsafe fn swap<T>(x: *mut T, y: *mut T) {
/// ///
/// Behavior is undefined if any of the following conditions are violated: /// Behavior is undefined if any of the following conditions are violated:
/// ///
/// * Both `x` and `y` must be [valid] for reads and writes of `count * /// * Both `x` and `y` must be [valid] for both reads and writes of `count *
/// size_of::<T>()` bytes. /// size_of::<T>()` bytes.
/// ///
/// * Both `x` and `y` must be properly aligned. /// * Both `x` and `y` must be properly aligned.
@ -471,10 +474,12 @@ unsafe fn swap_nonoverlapping_bytes(x: *mut u8, y: *mut u8, len: usize) {
/// ///
/// Behavior is undefined if any of the following conditions are violated: /// Behavior is undefined if any of the following conditions are violated:
/// ///
/// * `dst` must be [valid] for writes. /// * `dst` must be [valid] for both reads and writes.
/// ///
/// * `dst` must be properly aligned. /// * `dst` must be properly aligned.
/// ///
/// * `dst` must point to a properly initialized value of type `T`.
///
/// Note that even if `T` has size `0`, the pointer must be non-NULL and properly aligned. /// Note that even if `T` has size `0`, the pointer must be non-NULL and properly aligned.
/// ///
/// [valid]: ../ptr/index.html#safety /// [valid]: ../ptr/index.html#safety
@ -514,6 +519,8 @@ pub unsafe fn replace<T>(dst: *mut T, mut src: T) -> T {
/// * `src` must be properly aligned. Use [`read_unaligned`] if this is not the /// * `src` must be properly aligned. Use [`read_unaligned`] if this is not the
/// case. /// case.
/// ///
/// * `src` must point to a properly initialized value of type `T`.
///
/// Note that even if `T` has size `0`, the pointer must be non-NULL and properly aligned. /// Note that even if `T` has size `0`, the pointer must be non-NULL and properly aligned.
/// ///
/// # Examples /// # Examples
@ -628,6 +635,8 @@ pub unsafe fn read<T>(src: *const T) -> T {
/// ///
/// * `src` must be [valid] for reads. /// * `src` must be [valid] for reads.
/// ///
/// * `src` must point to a properly initialized value of type `T`.
///
/// Like [`read`], `read_unaligned` creates a bitwise copy of `T`, regardless of /// Like [`read`], `read_unaligned` creates a bitwise copy of `T`, regardless of
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned
/// value and the value at `*src` can [violate memory safety][read-ownership]. /// value and the value at `*src` can [violate memory safety][read-ownership].
@ -922,6 +931,8 @@ pub unsafe fn write_unaligned<T>(dst: *mut T, src: T) {
/// ///
/// * `src` must be properly aligned. /// * `src` must be properly aligned.
/// ///
/// * `src` must point to a properly initialized value of type `T`.
///
/// Like [`read`], `read_volatile` creates a bitwise copy of `T`, regardless of /// Like [`read`], `read_volatile` creates a bitwise copy of `T`, regardless of
/// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned /// whether `T` is [`Copy`]. If `T` is not [`Copy`], using both the returned
/// value and the value at `*src` can [violate memory safety][read-ownership]. /// value and the value at `*src` can [violate memory safety][read-ownership].

View File

@ -2658,7 +2658,8 @@ impl str {
/// ///
/// It's important to remember that [`char`] represents a Unicode Scalar /// It's important to remember that [`char`] represents a Unicode Scalar
/// Value, and may not match your idea of what a 'character' is. Iteration /// Value, and may not match your idea of what a 'character' is. Iteration
/// over grapheme clusters may be what you actually want. /// over grapheme clusters may be what you actually want. This functionality
/// is not provided by Rust's standard library, check crates.io instead.
/// ///
/// # Examples /// # Examples
/// ///

View File

@ -480,8 +480,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>, body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
) -> hir::ExprKind<'hir> { ) -> hir::ExprKind<'hir> {
let output = match ret_ty { let output = match ret_ty {
Some(ty) => FunctionRetTy::Ty(ty), Some(ty) => FnRetTy::Ty(ty),
None => FunctionRetTy::Default(span), None => FnRetTy::Default(span),
}; };
let ast_decl = FnDecl { inputs: vec![], output }; let ast_decl = FnDecl { inputs: vec![], output };
let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None); let decl = self.lower_fn_decl(&ast_decl, None, /* impl trait allowed */ false, None);
@ -721,7 +721,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn_decl_span: Span, fn_decl_span: Span,
) -> hir::ExprKind<'hir> { ) -> hir::ExprKind<'hir> {
let outer_decl = let outer_decl =
FnDecl { inputs: decl.inputs.clone(), output: FunctionRetTy::Default(fn_decl_span) }; FnDecl { inputs: decl.inputs.clone(), output: FnRetTy::Default(fn_decl_span) };
// We need to lower the declaration outside the new scope, because we // We need to lower the declaration outside the new scope, because we
// have to conserve the state of being inside a loop condition for the // have to conserve the state of being inside a loop condition for the
// closure argument types. // closure argument types.
@ -747,7 +747,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
// `|x: u8| future_from_generator(|| -> X { ... })`. // `|x: u8| future_from_generator(|| -> X { ... })`.
let body_id = this.lower_fn_body(&outer_decl, |this| { let body_id = this.lower_fn_body(&outer_decl, |this| {
let async_ret_ty = let async_ret_ty =
if let FunctionRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None }; if let FnRetTy::Ty(ty) = &decl.output { Some(ty.clone()) } else { None };
let async_body = this.make_async_expr( let async_body = this.make_async_expr(
capture_clause, capture_clause,
closure_id, closure_id,

View File

@ -1725,16 +1725,16 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
) )
} else { } else {
match decl.output { match decl.output {
FunctionRetTy::Ty(ref ty) => { FnRetTy::Ty(ref ty) => {
let context = match in_band_ty_params { let context = match in_band_ty_params {
Some((def_id, _)) if impl_trait_return_allow => { Some((def_id, _)) if impl_trait_return_allow => {
ImplTraitContext::OpaqueTy(Some(def_id), hir::OpaqueTyOrigin::FnReturn) ImplTraitContext::OpaqueTy(Some(def_id), hir::OpaqueTyOrigin::FnReturn)
} }
_ => ImplTraitContext::disallowed(), _ => ImplTraitContext::disallowed(),
}; };
hir::FunctionRetTy::Return(self.lower_ty(ty, context)) hir::FnRetTy::Return(self.lower_ty(ty, context))
} }
FunctionRetTy::Default(span) => hir::FunctionRetTy::DefaultReturn(span), FnRetTy::Default(span) => hir::FnRetTy::DefaultReturn(span),
} }
}; };
@ -1781,10 +1781,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// `elided_lt_replacement`: replacement for elided lifetimes in the return type // `elided_lt_replacement`: replacement for elided lifetimes in the return type
fn lower_async_fn_ret_ty( fn lower_async_fn_ret_ty(
&mut self, &mut self,
output: &FunctionRetTy, output: &FnRetTy,
fn_def_id: DefId, fn_def_id: DefId,
opaque_ty_node_id: NodeId, opaque_ty_node_id: NodeId,
) -> hir::FunctionRetTy<'hir> { ) -> hir::FnRetTy<'hir> {
debug!( debug!(
"lower_async_fn_ret_ty(\ "lower_async_fn_ret_ty(\
output={:?}, \ output={:?}, \
@ -1949,19 +1949,19 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
// only the lifetime parameters that we must supply. // only the lifetime parameters that we must supply.
let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args); let opaque_ty_ref = hir::TyKind::Def(hir::ItemId { id: opaque_ty_id }, generic_args);
let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref); let opaque_ty = self.ty(opaque_ty_span, opaque_ty_ref);
hir::FunctionRetTy::Return(self.arena.alloc(opaque_ty)) hir::FnRetTy::Return(self.arena.alloc(opaque_ty))
} }
/// Transforms `-> T` into `Future<Output = T>` /// Transforms `-> T` into `Future<Output = T>`
fn lower_async_fn_output_type_to_future_bound( fn lower_async_fn_output_type_to_future_bound(
&mut self, &mut self,
output: &FunctionRetTy, output: &FnRetTy,
fn_def_id: DefId, fn_def_id: DefId,
span: Span, span: Span,
) -> hir::GenericBound<'hir> { ) -> hir::GenericBound<'hir> {
// Compute the `T` in `Future<Output = T>` from the return type. // Compute the `T` in `Future<Output = T>` from the return type.
let output_ty = match output { let output_ty = match output {
FunctionRetTy::Ty(ty) => { FnRetTy::Ty(ty) => {
// Not `OpaqueTyOrigin::AsyncFn`: that's only used for the // Not `OpaqueTyOrigin::AsyncFn`: that's only used for the
// `impl Future` opaque type that `async fn` implicitly // `impl Future` opaque type that `async fn` implicitly
// generates. // generates.
@ -1969,7 +1969,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
ImplTraitContext::OpaqueTy(Some(fn_def_id), hir::OpaqueTyOrigin::FnReturn); ImplTraitContext::OpaqueTy(Some(fn_def_id), hir::OpaqueTyOrigin::FnReturn);
self.lower_ty(ty, context) self.lower_ty(ty, context)
} }
FunctionRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])), FnRetTy::Default(ret_ty_span) => self.arena.alloc(self.ty_tup(*ret_ty_span, &[])),
}; };
// "<Output = T>" // "<Output = T>"

View File

@ -397,8 +397,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())), inputs.iter().map(|ty| this.lower_ty_direct(ty, ImplTraitContext::disallowed())),
); );
let output_ty = match output { let output_ty = match output {
FunctionRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()), FnRetTy::Ty(ty) => this.lower_ty(&ty, ImplTraitContext::disallowed()),
FunctionRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])), FnRetTy::Default(_) => this.arena.alloc(this.ty_tup(span, &[])),
}; };
let args = smallvec![GenericArg::Type(this.ty_tup(span, inputs))]; let args = smallvec![GenericArg::Type(this.ty_tup(span, inputs))];
let binding = this.output_ty_binding(output_ty.span, output_ty); let binding = this.output_ty_binding(output_ty.span, output_ty);

View File

@ -954,7 +954,7 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
} }
GenericArgs::Parenthesized(ref data) => { GenericArgs::Parenthesized(ref data) => {
walk_list!(self, visit_ty, &data.inputs); walk_list!(self, visit_ty, &data.inputs);
if let FunctionRetTy::Ty(ty) = &data.output { if let FnRetTy::Ty(ty) = &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(ty)); self.with_impl_trait(None, |this| this.visit_ty(ty));

View File

@ -419,8 +419,8 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
visit::walk_ty(self, ty) visit::walk_ty(self, ty)
} }
fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FunctionRetTy) { fn visit_fn_ret_ty(&mut self, ret_ty: &'a ast::FnRetTy) {
if let ast::FunctionRetTy::Ty(ref output_ty) = *ret_ty { if let ast::FnRetTy::Ty(ref output_ty) = *ret_ty {
if let ast::TyKind::Never = output_ty.kind { if let ast::TyKind::Never = output_ty.kind {
// Do nothing. // Do nothing.
} else { } else {

View File

@ -2673,8 +2673,8 @@ impl<'a> State<'a> {
self.end(); self.end();
} }
crate fn print_fn_ret_ty(&mut self, fn_ret_ty: &ast::FunctionRetTy) { crate fn print_fn_ret_ty(&mut self, fn_ret_ty: &ast::FnRetTy) {
if let ast::FunctionRetTy::Ty(ty) = fn_ret_ty { if let ast::FnRetTy::Ty(ty) = fn_ret_ty {
self.space_if_not_bol(); self.space_if_not_bol();
self.ibox(INDENT_UNIT); self.ibox(INDENT_UNIT);
self.word_space("->"); self.word_space("->");

View File

@ -34,10 +34,8 @@ fn test_fun_to_string() {
with_default_globals(|| { with_default_globals(|| {
let abba_ident = ast::Ident::from_str("abba"); let abba_ident = ast::Ident::from_str("abba");
let decl = ast::FnDecl { let decl =
inputs: Vec::new(), ast::FnDecl { inputs: Vec::new(), output: ast::FnRetTy::Default(rustc_span::DUMMY_SP) };
output: ast::FunctionRetTy::Default(rustc_span::DUMMY_SP),
};
let generics = ast::Generics::default(); let generics = ast::Generics::default();
assert_eq!( assert_eq!(
fun_to_string(&decl, ast::FnHeader::default(), abba_ident, &generics), fun_to_string(&decl, ast::FnHeader::default(), abba_ident, &generics),

View File

@ -957,7 +957,7 @@ impl<'a> MethodDef<'a> {
let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident); let ret_type = self.get_ret_ty(cx, trait_, generics, type_ident);
let method_ident = cx.ident_of(self.name, trait_.span); let method_ident = cx.ident_of(self.name, trait_.span);
let fn_decl = cx.fn_decl(args, ast::FunctionRetTy::Ty(ret_type)); let fn_decl = cx.fn_decl(args, ast::FnRetTy::Ty(ret_type));
let body_block = cx.block_expr(body); let body_block = cx.block_expr(body);
let unsafety = if self.is_unsafe { ast::Unsafe::Yes(trait_.span) } else { ast::Unsafe::No }; let unsafety = if self.is_unsafe { ast::Unsafe::Yes(trait_.span) } else { ast::Unsafe::No };

View File

@ -63,7 +63,7 @@ impl AllocFnFactory<'_, '_> {
let args = method.inputs.iter().map(|ty| self.arg_ty(ty, &mut abi_args, mk)).collect(); let args = method.inputs.iter().map(|ty| self.arg_ty(ty, &mut abi_args, mk)).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 decl = self.cx.fn_decl(abi_args, ast::FunctionRetTy::Ty(output_ty)); let decl = self.cx.fn_decl(abi_args, ast::FnRetTy::Ty(output_ty));
let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() }; let header = FnHeader { unsafety: Unsafe::Yes(self.span), ..FnHeader::default() };
let sig = FnSig { decl, header }; let sig = FnSig { decl, header };
let kind = ItemKind::Fn(sig, Generics::default(), Some(self.cx.block_expr(output_expr))); let kind = ItemKind::Fn(sig, Generics::default(), Some(self.cx.block_expr(output_expr)));

View File

@ -391,8 +391,8 @@ 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 sig.decl.output { let has_output = match sig.decl.output {
ast::FunctionRetTy::Default(..) => false, ast::FnRetTy::Default(..) => false,
ast::FunctionRetTy::Ty(ref t) if t.kind.is_unit() => false, ast::FnRetTy::Ty(ref t) if t.kind.is_unit() => false,
_ => true, _ => true,
}; };

View File

@ -305,7 +305,7 @@ fn mk_main(cx: &mut TestCtxt<'_>) -> P<ast::Item> {
ecx.block(sp, vec![call_test_main]) ecx.block(sp, vec![call_test_main])
}; };
let decl = ecx.fn_decl(vec![], ast::FunctionRetTy::Ty(main_ret_ty)); let decl = ecx.fn_decl(vec![], ast::FnRetTy::Ty(main_ret_ty));
let sig = ast::FnSig { decl, header: ast::FnHeader::default() }; let sig = ast::FnSig { decl, header: ast::FnHeader::default() };
let main = ast::ItemKind::Fn(sig, ast::Generics::default(), Some(main_body)); let main = ast::ItemKind::Fn(sig, ast::Generics::default(), Some(main_body));

View File

@ -1,9 +1,7 @@
The type definition contains some field whose type A parameter type is missing an explicit lifetime bound and may not live long
requires an outlives annotation. Outlives annotations enough.
(e.g., `T: 'a`) are used to guarantee that all the data in T is valid
for at least the lifetime `'a`. This scenario most commonly Erroneous code example:
arises when the type contains an associated type reference
like `<T as SomeTrait<'a>>::Output`, as shown in this example:
```compile_fail,E0309 ```compile_fail,E0309
// This won't compile because the applicable impl of // This won't compile because the applicable impl of
@ -25,9 +23,15 @@ where
} }
``` ```
Here, the where clause `T: 'a` that appears on the impl is not known to be The type definition contains some field whose type requires an outlives
satisfied on the struct. To make this example compile, you have to add annotation. Outlives annotations (e.g., `T: 'a`) are used to guarantee that all
a where-clause like `T: 'a` to the struct definition: the data in T is valid for at least the lifetime `'a`. This scenario most
commonly arises when the type contains an associated type reference like
`<T as SomeTrait<'a>>::Output`, as shown in the previous code.
There, the where clause `T: 'a` that appears on the impl is not known to be
satisfied on the struct. To make this example compile, you have to add a
where-clause like `T: 'a` to the struct definition:
``` ```
struct Foo<'a, T> struct Foo<'a, T>

View File

@ -519,7 +519,7 @@ impl<'a> ExtCtxt<'a> {
pub fn lambda(&self, span: Span, ids: Vec<ast::Ident>, body: P<ast::Expr>) -> P<ast::Expr> { pub fn lambda(&self, span: Span, ids: Vec<ast::Ident>, body: P<ast::Expr>) -> P<ast::Expr> {
let fn_decl = self.fn_decl( let fn_decl = self.fn_decl(
ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(), ids.iter().map(|id| self.param(span, *id, self.ty(span, ast::TyKind::Infer))).collect(),
ast::FunctionRetTy::Default(span), ast::FnRetTy::Default(span),
); );
// FIXME -- We are using `span` as the span of the `|...|` // FIXME -- We are using `span` as the span of the `|...|`
@ -569,7 +569,7 @@ impl<'a> ExtCtxt<'a> {
} }
// FIXME: unused `self` // FIXME: unused `self`
pub fn fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FunctionRetTy) -> P<ast::FnDecl> { pub fn fn_decl(&self, inputs: Vec<ast::Param>, output: ast::FnRetTy) -> P<ast::FnDecl> {
P(ast::FnDecl { inputs, output }) P(ast::FnDecl { inputs, output })
} }

View File

@ -109,7 +109,7 @@ use crate::mbe::{KleeneToken, TokenTree};
use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::fx::FxHashMap;
use rustc_session::lint::builtin::META_VARIABLE_MISUSE; use rustc_session::lint::builtin::META_VARIABLE_MISUSE;
use rustc_session::parse::ParseSess; use rustc_session::parse::ParseSess;
use rustc_span::symbol::{kw, sym}; use rustc_span::symbol::kw;
use rustc_span::{symbol::Ident, MultiSpan, Span}; use rustc_span::{symbol::Ident, MultiSpan, Span};
use syntax::ast::NodeId; use syntax::ast::NodeId;
use syntax::token::{DelimToken, Token, TokenKind}; use syntax::token::{DelimToken, Token, TokenKind};
@ -392,7 +392,7 @@ fn check_nested_occurrences(
NestedMacroState::Empty, NestedMacroState::Empty,
&TokenTree::Token(Token { kind: TokenKind::Ident(name, false), .. }), &TokenTree::Token(Token { kind: TokenKind::Ident(name, false), .. }),
) => { ) => {
if name == sym::macro_rules { if name == kw::MacroRules {
state = NestedMacroState::MacroRules; state = NestedMacroState::MacroRules;
} else if name == kw::Macro { } else if name == kw::Macro {
state = NestedMacroState::Macro; state = NestedMacroState::Macro;

View File

@ -65,7 +65,7 @@ fn string_to_tts_macro() {
match tts { match tts {
[TokenTree::Token(Token { kind: token::Ident(name_macro_rules, false), .. }), TokenTree::Token(Token { kind: token::Not, .. }), TokenTree::Token(Token { kind: token::Ident(name_zip, false), .. }), TokenTree::Delimited(_, macro_delim, macro_tts)] [TokenTree::Token(Token { kind: token::Ident(name_macro_rules, false), .. }), TokenTree::Token(Token { kind: token::Not, .. }), TokenTree::Token(Token { kind: token::Ident(name_zip, false), .. }), TokenTree::Delimited(_, macro_delim, macro_tts)]
if name_macro_rules == &sym::macro_rules && name_zip.as_str() == "zip" => if name_macro_rules == &kw::MacroRules && name_zip.as_str() == "zip" =>
{ {
let tts = &macro_tts.trees().collect::<Vec<_>>(); let tts = &macro_tts.trees().collect::<Vec<_>>();
match &tts[..] { match &tts[..] {

View File

@ -5,7 +5,7 @@ use crate::itemlikevisit;
use crate::print; use crate::print;
crate use BlockCheckMode::*; crate use BlockCheckMode::*;
crate use FunctionRetTy::*; crate use FnRetTy::*;
crate use UnsafeSource::*; crate use UnsafeSource::*;
use rustc_data_structures::fx::FxHashSet; use rustc_data_structures::fx::FxHashSet;
@ -2082,7 +2082,7 @@ pub struct FnDecl<'hir> {
/// ///
/// Additional argument data is stored in the function's [body](Body::parameters). /// Additional argument data is stored in the function's [body](Body::parameters).
pub inputs: &'hir [Ty<'hir>], pub inputs: &'hir [Ty<'hir>],
pub output: FunctionRetTy<'hir>, pub output: FnRetTy<'hir>,
pub c_variadic: bool, pub c_variadic: bool,
/// Does the function have an implicit self? /// Does the function have an implicit self?
pub implicit_self: ImplicitSelfKind, pub implicit_self: ImplicitSelfKind,
@ -2148,7 +2148,7 @@ impl Defaultness {
} }
#[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)] #[derive(RustcEncodable, RustcDecodable, Debug, HashStable_Generic)]
pub enum FunctionRetTy<'hir> { pub enum FnRetTy<'hir> {
/// Return type is not specified. /// Return type is not specified.
/// ///
/// Functions default to `()` and /// Functions default to `()` and
@ -2159,7 +2159,7 @@ pub enum FunctionRetTy<'hir> {
Return(&'hir Ty<'hir>), Return(&'hir Ty<'hir>),
} }
impl fmt::Display for FunctionRetTy<'_> { impl fmt::Display for FnRetTy<'_> {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
Self::Return(ref ty) => print::to_string(print::NO_ANN, |s| s.print_type(ty)).fmt(f), Self::Return(ref ty) => print::to_string(print::NO_ANN, |s| s.print_type(ty)).fmt(f),
@ -2168,7 +2168,7 @@ impl fmt::Display for FunctionRetTy<'_> {
} }
} }
impl FunctionRetTy<'_> { impl FnRetTy<'_> {
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match *self { match *self {
Self::DefaultReturn(span) => span, Self::DefaultReturn(span) => span,

View File

@ -865,8 +865,8 @@ pub fn walk_where_predicate<'v, V: Visitor<'v>>(
} }
} }
pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FunctionRetTy<'v>) { pub fn walk_fn_ret_ty<'v, V: Visitor<'v>>(visitor: &mut V, ret_ty: &'v FnRetTy<'v>) {
if let FunctionRetTy::Return(ref output_ty) = *ret_ty { if let FnRetTy::Return(ref output_ty) = *ret_ty {
visitor.visit_ty(output_ty) visitor.visit_ty(output_ty)
} }
} }

View File

@ -7,7 +7,7 @@ use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir as hir; use rustc_hir as hir;
use rustc_hir::def::{DefKind, Namespace}; use rustc_hir::def::{DefKind, Namespace};
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor}; use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
use rustc_hir::{Body, Expr, ExprKind, FunctionRetTy, HirId, Local, Pat}; use rustc_hir::{Body, Expr, ExprKind, FnRetTy, HirId, Local, Pat};
use rustc_span::source_map::DesugaringKind; use rustc_span::source_map::DesugaringKind;
use rustc_span::symbol::kw; use rustc_span::symbol::kw;
use rustc_span::Span; use rustc_span::Span;
@ -108,7 +108,7 @@ impl<'a, 'tcx> Visitor<'tcx> for FindLocalByTypeVisitor<'a, 'tcx> {
fn closure_return_type_suggestion( fn closure_return_type_suggestion(
span: Span, span: Span,
err: &mut DiagnosticBuilder<'_>, err: &mut DiagnosticBuilder<'_>,
output: &FunctionRetTy<'_>, output: &FnRetTy<'_>,
body: &Body<'_>, body: &Body<'_>,
descr: &str, descr: &str,
name: &str, name: &str,
@ -117,7 +117,7 @@ fn closure_return_type_suggestion(
parent_descr: Option<&str>, parent_descr: Option<&str>,
) { ) {
let (arrow, post) = match output { let (arrow, post) = match output {
FunctionRetTy::DefaultReturn(_) => ("-> ", " "), FnRetTy::DefaultReturn(_) => ("-> ", " "),
_ => ("", ""), _ => ("", ""),
}; };
let suggestion = match body.value.kind { let suggestion = match body.value.kind {

View File

@ -3,7 +3,7 @@
use crate::infer::error_reporting::nice_region_error::NiceRegionError; use crate::infer::error_reporting::nice_region_error::NiceRegionError;
use rustc::ty; use rustc::ty;
use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder}; use rustc_errors::{struct_span_err, Applicability, DiagnosticBuilder};
use rustc_hir::{FunctionRetTy, TyKind}; use rustc_hir::{FnRetTy, TyKind};
impl<'a, 'tcx> NiceRegionError<'a, 'tcx> { impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
/// When given a `ConcreteFailure` for a function with parameters containing a named region and /// When given a `ConcreteFailure` for a function with parameters containing a named region and
@ -79,7 +79,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
{ {
return None; return None;
} }
if let FunctionRetTy::Return(ty) = &fndecl.output { if let FnRetTy::Return(ty) = &fndecl.output {
if let (TyKind::Def(_, _), ty::ReStatic) = (&ty.kind, sub) { if let (TyKind::Def(_, _), ty::ReStatic) = (&ty.kind, sub) {
// This is an impl Trait return that evaluates de need of 'static. // This is an impl Trait return that evaluates de need of 'static.
// We handle this case better in `static_impl_trait`. // We handle this case better in `static_impl_trait`.

View File

@ -594,7 +594,7 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
_ => return false, _ => return false,
}; };
let ret_ty = if let hir::FunctionRetTy::Return(ret_ty) = sig.decl.output { let ret_ty = if let hir::FnRetTy::Return(ret_ty) = sig.decl.output {
ret_ty ret_ty
} else { } else {
return false; return false;

View File

@ -620,8 +620,8 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
ret ret
} }
fn should_ignore_fn(ret_ty: &ast::FunctionRetTy) -> bool { fn should_ignore_fn(ret_ty: &ast::FnRetTy) -> bool {
if let ast::FunctionRetTy::Ty(ref ty) = ret_ty { if let ast::FnRetTy::Ty(ref ty) = ret_ty {
fn involves_impl_trait(ty: &ast::Ty) -> bool { fn involves_impl_trait(ty: &ast::Ty) -> bool {
match ty.kind { match ty.kind {
ast::TyKind::ImplTrait(..) => true, ast::TyKind::ImplTrait(..) => true,

View File

@ -953,7 +953,7 @@ impl<'a, 'tcx> ImproperCTypesVisitor<'a, 'tcx> {
self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false); self.check_type_for_ffi_and_report_errors(input_hir.span, input_ty, false);
} }
if let hir::FunctionRetTy::Return(ref ret_hir) = decl.output { if let hir::FnRetTy::Return(ref ret_hir) = decl.output {
let ret_ty = sig.output(); let ret_ty = sig.output();
if !ret_ty.is_unit() { if !ret_ty.is_unit() {
self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false); self.check_type_for_ffi_and_report_errors(ret_hir.span, ret_ty, false);

View File

@ -1885,7 +1885,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// as the HIR doesn't have full types for closure arguments. // as the HIR doesn't have full types for closure arguments.
let return_ty = *sig.output().skip_binder(); let return_ty = *sig.output().skip_binder();
let mut return_span = fn_decl.output.span(); let mut return_span = fn_decl.output.span();
if let hir::FunctionRetTy::Return(ty) = &fn_decl.output { if let hir::FnRetTy::Return(ty) = &fn_decl.output {
if let hir::TyKind::Rptr(lifetime, _) = ty.kind { if let hir::TyKind::Rptr(lifetime, _) = ty.kind {
return_span = lifetime.span; return_span = lifetime.span;
} }

View File

@ -645,8 +645,8 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
.. ..
}) => ( }) => (
match return_ty.output { match return_ty.output {
hir::FunctionRetTy::DefaultReturn(_) => tcx.sess.source_map().end_point(*span), hir::FnRetTy::DefaultReturn(_) => tcx.sess.source_map().end_point(*span),
hir::FunctionRetTy::Return(_) => return_ty.output.span(), hir::FnRetTy::Return(_) => return_ty.output.span(),
}, },
if gen_move.is_some() { " of generator" } else { " of closure" }, if gen_move.is_some() { " of generator" } else { " of closure" },
), ),

View File

@ -195,6 +195,8 @@ where
// C: Entry state // C: Entry state
self.bg = Background::Light; self.bg = Background::Light;
self.results.seek_to_block_start(block); self.results.seek_to_block_start(block);
let block_entry_state = self.results.get().clone();
self.write_row_with_full_state(w, "", "(on entry)")?; self.write_row_with_full_state(w, "", "(on entry)")?;
// D: Statement transfer functions // D: Statement transfer functions
@ -213,29 +215,42 @@ where
self.write_row_for_location(w, "T", &terminator_str, terminator_loc)?; self.write_row_for_location(w, "T", &terminator_str, terminator_loc)?;
// F: Exit state // F: Exit state
// Write the full dataflow state immediately after the terminator if it differs from the
// state at block entry.
self.results.seek_after(terminator_loc); self.results.seek_after(terminator_loc);
if let mir::TerminatorKind::Call { destination: Some(_), .. } = &terminator.kind { if self.results.get() != &block_entry_state {
self.write_row_with_full_state(w, "", "(on unwind)")?; let after_terminator_name = match terminator.kind {
mir::TerminatorKind::Call { destination: Some(_), .. } => "(on unwind)",
_ => "(on exit)",
};
let num_state_columns = self.num_state_columns(); self.write_row_with_full_state(w, "", after_terminator_name)?;
self.write_row(w, "", "(on successful return)", |this, w, fmt| {
write!(
w,
r#"<td balign="left" colspan="{colspan}" {fmt} align="left">"#,
colspan = num_state_columns,
fmt = fmt,
)?;
let state_on_unwind = this.results.get().clone();
this.results.seek_after_assume_call_returns(terminator_loc);
write_diff(w, this.results.analysis(), &state_on_unwind, this.results.get())?;
write!(w, "</td>")
})?;
} else {
self.write_row_with_full_state(w, "", "(on exit)")?;
} }
// Write any changes caused by terminator-specific effects
match terminator.kind {
mir::TerminatorKind::Call { destination: Some(_), .. } => {
let num_state_columns = self.num_state_columns();
self.write_row(w, "", "(on successful return)", |this, w, fmt| {
write!(
w,
r#"<td balign="left" colspan="{colspan}" {fmt} align="left">"#,
colspan = num_state_columns,
fmt = fmt,
)?;
let state_on_unwind = this.results.get().clone();
this.results.seek_after_assume_call_returns(terminator_loc);
write_diff(w, this.results.analysis(), &state_on_unwind, this.results.get())?;
write!(w, "</td>")
})?;
}
_ => {}
};
write!(w, "</table>") write!(w, "</table>")
} }

View File

@ -10,9 +10,7 @@ use rustc_span::source_map::{self, Span, Spanned};
use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::symbol::{kw, sym, Symbol};
use std::mem; use std::mem;
use syntax::ast::{self, AttrStyle, AttrVec, CaptureBy, Field, Ident, Lit, DUMMY_NODE_ID}; use syntax::ast::{self, AttrStyle, AttrVec, CaptureBy, Field, Ident, Lit, DUMMY_NODE_ID};
use syntax::ast::{ use syntax::ast::{AnonConst, BinOp, BinOpKind, FnDecl, FnRetTy, Mac, Param, Ty, TyKind, UnOp};
AnonConst, BinOp, BinOpKind, FnDecl, FunctionRetTy, Mac, Param, Ty, TyKind, UnOp,
};
use syntax::ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits}; use syntax::ast::{Arm, Async, BlockCheckMode, Expr, ExprKind, Label, Movability, RangeLimits};
use syntax::ptr::P; use syntax::ptr::P;
use syntax::token::{self, Token, TokenKind}; use syntax::token::{self, Token, TokenKind};
@ -1358,7 +1356,7 @@ impl<'a> Parser<'a> {
let decl = self.parse_fn_block_decl()?; let decl = self.parse_fn_block_decl()?;
let decl_hi = self.prev_span; let decl_hi = self.prev_span;
let body = match decl.output { let body = match decl.output {
FunctionRetTy::Default(_) => { FnRetTy::Default(_) => {
let restrictions = self.restrictions - Restrictions::STMT_EXPR; let restrictions = self.restrictions - Restrictions::STMT_EXPR;
self.parse_expr_res(restrictions, None)? self.parse_expr_res(restrictions, None)?
} }

View File

@ -1343,14 +1343,14 @@ impl<'a> Parser<'a> {
/// Is this unambiguously the start of a `macro_rules! foo` item defnition? /// Is this unambiguously the start of a `macro_rules! foo` item defnition?
fn is_macro_rules_item(&mut self) -> bool { fn is_macro_rules_item(&mut self) -> bool {
self.check_keyword(sym::macro_rules) self.check_keyword(kw::MacroRules)
&& self.look_ahead(1, |t| *t == token::Not) && self.look_ahead(1, |t| *t == token::Not)
&& self.look_ahead(2, |t| t.is_ident()) && self.look_ahead(2, |t| t.is_ident())
} }
/// Parses a legacy `macro_rules! foo { ... }` declarative macro. /// Parses a legacy `macro_rules! foo { ... }` declarative macro.
fn parse_item_macro_rules(&mut self, vis: &Visibility) -> PResult<'a, ItemInfo> { fn parse_item_macro_rules(&mut self, vis: &Visibility) -> PResult<'a, ItemInfo> {
self.expect_keyword(sym::macro_rules)?; // `macro_rules` self.expect_keyword(kw::MacroRules)?; // `macro_rules`
self.expect(&token::Not)?; // `!` self.expect(&token::Not)?; // `!`
let ident = self.parse_ident()?; let ident = self.parse_ident()?;

View File

@ -5,9 +5,7 @@ use crate::{maybe_recover_from_interpolated_ty_qpath, maybe_whole};
use rustc_errors::{pluralize, struct_span_err, Applicability, PResult}; use rustc_errors::{pluralize, struct_span_err, Applicability, PResult};
use rustc_span::source_map::Span; use rustc_span::source_map::Span;
use rustc_span::symbol::{kw, sym}; use rustc_span::symbol::{kw, sym};
use syntax::ast::{ use syntax::ast::{self, BareFnTy, FnRetTy, GenericParam, Ident, Lifetime, MutTy, Ty, TyKind};
self, BareFnTy, FunctionRetTy, GenericParam, Ident, Lifetime, MutTy, Ty, TyKind,
};
use syntax::ast::{ use syntax::ast::{
GenericBound, GenericBounds, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax, GenericBound, GenericBounds, PolyTraitRef, TraitBoundModifier, TraitObjectSyntax,
}; };
@ -91,13 +89,13 @@ impl<'a> Parser<'a> {
&mut self, &mut self,
allow_plus: AllowPlus, allow_plus: AllowPlus,
recover_qpath: RecoverQPath, recover_qpath: RecoverQPath,
) -> PResult<'a, FunctionRetTy> { ) -> PResult<'a, FnRetTy> {
Ok(if self.eat(&token::RArrow) { Ok(if self.eat(&token::RArrow) {
// FIXME(Centril): Can we unconditionally `allow_plus`? // FIXME(Centril): Can we unconditionally `allow_plus`?
let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?; let ty = self.parse_ty_common(allow_plus, recover_qpath, AllowCVariadic::No)?;
FunctionRetTy::Ty(ty) FnRetTy::Ty(ty)
} else { } else {
FunctionRetTy::Default(self.token.span.shrink_to_lo()) FnRetTy::Default(self.token.span.shrink_to_lo())
}) })
} }

View File

@ -2035,7 +2035,7 @@ impl<'a, 'b, 'ast> LateResolutionVisitor<'a, 'b, 'ast> {
// Resolve arguments: // Resolve arguments:
this.resolve_params(&fn_decl.inputs); this.resolve_params(&fn_decl.inputs);
// No need to resolve return type -- // No need to resolve return type --
// the outer closure return type is `FunctionRetTy::Default`. // the outer closure return type is `FnRetTy::Default`.
// Now resolve the inner closure // Now resolve the inner closure
{ {

View File

@ -881,8 +881,8 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> {
fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) { fn visit_fn_decl(&mut self, fd: &'tcx hir::FnDecl<'tcx>) {
let output = match fd.output { let output = match fd.output {
hir::FunctionRetTy::DefaultReturn(_) => None, hir::FnRetTy::DefaultReturn(_) => None,
hir::FunctionRetTy::Return(ref ty) => Some(&**ty), hir::FnRetTy::Return(ref ty) => Some(&**ty),
}; };
self.visit_fn_like_elision(&fd.inputs, output); self.visit_fn_like_elision(&fd.inputs, output);
} }

View File

@ -285,7 +285,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
v.visit_ty(&arg.ty); v.visit_ty(&arg.ty);
} }
if let ast::FunctionRetTy::Ty(ref ret_ty) = sig.decl.output { if let ast::FnRetTy::Ty(ref ret_ty) = sig.decl.output {
// In async functions, return types are desugared and redefined // In async functions, return types are desugared and redefined
// as an `impl Trait` existential type. Because of this, to match // as an `impl Trait` existential type. Because of this, to match
// the definition paths when resolving nested types we need to // the definition paths when resolving nested types we need to
@ -374,7 +374,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
v.visit_ty(&arg.ty) v.visit_ty(&arg.ty)
} }
if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output { if let ast::FnRetTy::Ty(ref ret_ty) = decl.output {
if let ast::TyKind::ImplTrait(..) = ret_ty.kind { if let ast::TyKind::ImplTrait(..) = ret_ty.kind {
// FIXME: Opaque type desugaring prevents us from easily // FIXME: Opaque type desugaring prevents us from easily
// processing trait bounds. See `visit_ty` for more details. // processing trait bounds. See `visit_ty` for more details.
@ -792,7 +792,7 @@ impl<'l, 'tcx> DumpVisitor<'l, 'tcx> {
for t in &data.inputs { for t in &data.inputs {
self.visit_ty(t); self.visit_ty(t);
} }
if let ast::FunctionRetTy::Ty(ty) = &data.output { if let ast::FnRetTy::Ty(ty) = &data.output {
self.visit_ty(ty); self.visit_ty(ty);
} }
} }
@ -1449,7 +1449,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
self.visit_ty(&arg.ty); self.visit_ty(&arg.ty);
} }
if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output { if let ast::FnRetTy::Ty(ref ret_ty) = decl.output {
self.visit_ty(&ret_ty); self.visit_ty(&ret_ty);
} }
@ -1528,7 +1528,7 @@ impl<'l, 'tcx> Visitor<'l> for DumpVisitor<'l, 'tcx> {
self.visit_ty(&arg.ty); self.visit_ty(&arg.ty);
} }
if let ast::FunctionRetTy::Ty(ref ret_ty) = decl.output { if let ast::FnRetTy::Ty(ref ret_ty) = decl.output {
self.visit_ty(&ret_ty); self.visit_ty(&ret_ty);
} }
} }

View File

@ -880,8 +880,8 @@ fn make_signature(decl: &ast::FnDecl, generics: &ast::Generics) -> String {
sig.push_str(&decl.inputs.iter().map(param_to_string).collect::<Vec<_>>().join(", ")); sig.push_str(&decl.inputs.iter().map(param_to_string).collect::<Vec<_>>().join(", "));
sig.push(')'); sig.push(')');
match decl.output { match decl.output {
ast::FunctionRetTy::Default(_) => sig.push_str(" -> ()"), ast::FnRetTy::Default(_) => sig.push_str(" -> ()"),
ast::FunctionRetTy::Ty(ref t) => sig.push_str(&format!(" -> {}", ty_to_string(t))), ast::FnRetTy::Ty(ref t) => sig.push_str(&format!(" -> {}", ty_to_string(t))),
} }
sig sig

View File

@ -241,7 +241,7 @@ impl Sig for ast::Ty {
refs.extend(nested.refs.into_iter()); refs.extend(nested.refs.into_iter());
} }
text.push(')'); text.push(')');
if let ast::FunctionRetTy::Ty(ref t) = f.decl.output { if let ast::FnRetTy::Ty(ref t) = f.decl.output {
text.push_str(" -> "); text.push_str(" -> ");
let nested = t.make(offset + text.len(), None, scx)?; let nested = t.make(offset + text.len(), None, scx)?;
text.push_str(&nested.text); text.push_str(&nested.text);
@ -392,7 +392,7 @@ impl Sig for ast::Item {
} }
sig.text.push(')'); sig.text.push(')');
if let ast::FunctionRetTy::Ty(ref t) = decl.output { if let ast::FnRetTy::Ty(ref t) = decl.output {
sig.text.push_str(" -> "); sig.text.push_str(" -> ");
let nested = t.make(offset + sig.text.len(), None, scx)?; let nested = t.make(offset + sig.text.len(), None, scx)?;
sig.text.push_str(&nested.text); sig.text.push_str(&nested.text);
@ -743,7 +743,7 @@ impl Sig for ast::ForeignItem {
} }
sig.text.push(')'); sig.text.push(')');
if let ast::FunctionRetTy::Ty(ref t) = decl.output { if let ast::FnRetTy::Ty(ref t) = decl.output {
sig.text.push_str(" -> "); sig.text.push_str(" -> ");
let nested = t.make(offset + sig.text.len(), None, scx)?; let nested = t.make(offset + sig.text.len(), None, scx)?;
sig.text.push_str(&nested.text); sig.text.push_str(&nested.text);
@ -911,7 +911,7 @@ fn make_method_signature(
} }
sig.text.push(')'); sig.text.push(')');
if let ast::FunctionRetTy::Ty(ref t) = m.decl.output { if let ast::FnRetTy::Ty(ref t) = m.decl.output {
sig.text.push_str(" -> "); sig.text.push_str(" -> ");
let nested = t.make(sig.text.len(), None, scx)?; let nested = t.make(sig.text.len(), None, scx)?;
sig.text.push_str(&nested.text); sig.text.push_str(&nested.text);

View File

@ -97,6 +97,7 @@ symbols! {
Auto: "auto", Auto: "auto",
Catch: "catch", Catch: "catch",
Default: "default", Default: "default",
MacroRules: "macro_rules",
Raw: "raw", Raw: "raw",
Union: "union", Union: "union",
} }
@ -429,7 +430,6 @@ symbols! {
macro_lifetime_matcher, macro_lifetime_matcher,
macro_literal_matcher, macro_literal_matcher,
macro_reexport, macro_reexport,
macro_rules,
macros_in_extern, macros_in_extern,
macro_use, macro_use,
macro_vis_matcher, macro_vis_matcher,
@ -1071,6 +1071,9 @@ pub mod sym {
symbols!(); symbols!();
// Used from a macro in `librustc_feature/accepted.rs`
pub use super::kw::MacroRules as macro_rules;
// Get the symbol for an integer. The first few non-negative integers each // Get the symbol for an integer. The first few non-negative integers each
// have a static symbol and therefore are fast. // have a static symbol and therefore are fast.
pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol { pub fn integer<N: TryInto<usize> + Copy + ToString>(n: N) -> Symbol {

View File

@ -2827,11 +2827,11 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
} }
let input_tys = decl.inputs.iter().map(|a| self.ty_of_arg(a, None)); let input_tys = decl.inputs.iter().map(|a| self.ty_of_arg(a, None));
let output_ty = match decl.output { let output_ty = match decl.output {
hir::FunctionRetTy::Return(ref output) => { hir::FnRetTy::Return(ref output) => {
visitor.visit_ty(output); visitor.visit_ty(output);
self.ast_ty_to_ty(output) self.ast_ty_to_ty(output)
} }
hir::FunctionRetTy::DefaultReturn(..) => tcx.mk_unit(), hir::FnRetTy::DefaultReturn(..) => tcx.mk_unit(),
}; };
debug!("ty_of_fn: output_ty={:?}", output_ty); debug!("ty_of_fn: output_ty={:?}", output_ty);

View File

@ -555,8 +555,8 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// First, convert the types that the user supplied (if any). // First, convert the types that the user supplied (if any).
let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a)); let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a));
let supplied_return = match decl.output { let supplied_return = match decl.output {
hir::FunctionRetTy::Return(ref output) => astconv.ast_ty_to_ty(&output), hir::FnRetTy::Return(ref output) => astconv.ast_ty_to_ty(&output),
hir::FunctionRetTy::DefaultReturn(_) => match body.generator_kind { hir::FnRetTy::DefaultReturn(_) => match body.generator_kind {
// In the case of the async block that we create for a function body, // In the case of the async block that we create for a function body,
// we expect the return type of the block to match that of the enclosing // we expect the return type of the block to match that of the enclosing
// function. // function.
@ -703,7 +703,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx.types.err self.tcx.types.err
}); });
if let hir::FunctionRetTy::Return(ref output) = decl.output { if let hir::FnRetTy::Return(ref output) = decl.output {
astconv.ast_ty_to_ty(&output); astconv.ast_ty_to_ty(&output);
} }

View File

@ -1363,7 +1363,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fcx: &FnCtxt<'a, 'tcx>, fcx: &FnCtxt<'a, 'tcx>,
expected: Ty<'tcx>, expected: Ty<'tcx>,
sp: Span, sp: Span,
fn_output: &hir::FunctionRetTy<'_>, fn_output: &hir::FnRetTy<'_>,
) { ) {
let return_sp = fn_output.span(); let return_sp = fn_output.span();
err.span_label(return_sp, "expected because this return type..."); err.span_label(return_sp, "expected because this return type...");
@ -1389,7 +1389,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
let has_impl = snippet_iter.next().map_or(false, |s| s == "impl"); let has_impl = snippet_iter.next().map_or(false, |s| s == "impl");
// Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe. // Only suggest `Box<dyn Trait>` if `Trait` in `impl Trait` is object safe.
let mut is_object_safe = false; let mut is_object_safe = false;
if let hir::FunctionRetTy::Return(ty) = fn_output { if let hir::FnRetTy::Return(ty) = fn_output {
// Get the return type. // Get the return type.
if let hir::TyKind::Def(..) = ty.kind { if let hir::TyKind::Def(..) = ty.kind {
let ty = AstConv::ast_ty_to_ty(fcx, ty); let ty = AstConv::ast_ty_to_ty(fcx, ty);
@ -1430,7 +1430,7 @@ impl<'tcx, 'exprs, E: AsCoercionSite> CoerceMany<'tcx, 'exprs, E> {
fn is_return_ty_unsized(&self, fcx: &FnCtxt<'a, 'tcx>, blk_id: hir::HirId) -> bool { fn is_return_ty_unsized(&self, fcx: &FnCtxt<'a, 'tcx>, blk_id: hir::HirId) -> bool {
if let Some((fn_decl, _)) = fcx.get_fn_decl(blk_id) { if let Some((fn_decl, _)) = fcx.get_fn_decl(blk_id) {
if let hir::FunctionRetTy::Return(ty) = fn_decl.output { if let hir::FnRetTy::Return(ty) = fn_decl.output {
let ty = AstConv::ast_ty_to_ty(fcx, ty); let ty = AstConv::ast_ty_to_ty(fcx, ty);
if let ty::Dynamic(..) = ty.kind { if let ty::Dynamic(..) = ty.kind {
return true; return true;

View File

@ -5153,7 +5153,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Only suggest changing the return type for methods that // Only suggest changing the return type for methods that
// haven't set a return type at all (and aren't `fn main()` or an impl). // haven't set a return type at all (and aren't `fn main()` or an impl).
match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) { match (&fn_decl.output, found.is_suggestable(), can_suggest, expected.is_unit()) {
(&hir::FunctionRetTy::DefaultReturn(span), true, true, true) => { (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
err.span_suggestion( err.span_suggestion(
span, span,
"try adding a return type", "try adding a return type",
@ -5162,18 +5162,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
); );
true true
} }
(&hir::FunctionRetTy::DefaultReturn(span), false, true, true) => { (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
err.span_label(span, "possibly return type missing here?"); err.span_label(span, "possibly return type missing here?");
true true
} }
(&hir::FunctionRetTy::DefaultReturn(span), _, false, true) => { (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
// `fn main()` must return `()`, do not suggest changing return type // `fn main()` must return `()`, do not suggest changing return type
err.span_label(span, "expected `()` because of default return type"); err.span_label(span, "expected `()` because of default return type");
true true
} }
// expectation was caused by something else, not the default return // expectation was caused by something else, not the default return
(&hir::FunctionRetTy::DefaultReturn(_), _, _, false) => false, (&hir::FnRetTy::DefaultReturn(_), _, _, false) => false,
(&hir::FunctionRetTy::Return(ref ty), _, _, _) => { (&hir::FnRetTy::Return(ref ty), _, _, _) => {
// Only point to return type if the expected type is the return type, as if they // Only point to return type if the expected type is the return type, as if they
// are not, the expectation must have been caused by something else. // are not, the expectation must have been caused by something else.
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind); debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);

View File

@ -214,7 +214,7 @@ fn check_object_unsafe_self_trait_by_name(tcx: TyCtxt<'_>, item: &hir::TraitItem
} }
} }
match sig.decl.output { match sig.decl.output {
hir::FunctionRetTy::Return(ty) if could_be_self(trait_def_id, ty) => { hir::FnRetTy::Return(ty) if could_be_self(trait_def_id, ty) => {
trait_should_be_self.push(ty.span); trait_should_be_self.push(ty.span);
} }
_ => {} _ => {}

View File

@ -1360,8 +1360,8 @@ fn is_suggestable_infer_ty(ty: &hir::Ty<'_>) -> bool {
} }
} }
pub fn get_infer_ret_ty(output: &'hir hir::FunctionRetTy<'hir>) -> Option<&'hir hir::Ty<'hir>> { pub fn get_infer_ret_ty(output: &'hir hir::FnRetTy<'hir>) -> Option<&'hir hir::Ty<'hir>> {
if let hir::FunctionRetTy::Return(ref ty) = output { if let hir::FnRetTy::Return(ref ty) = output {
if is_suggestable_infer_ty(ty) { if is_suggestable_infer_ty(ty) {
return Some(&**ty); return Some(&**ty);
} }
@ -2079,7 +2079,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) { for (input, ty) in decl.inputs.iter().zip(*fty.inputs().skip_binder()) {
check(&input, ty) check(&input, ty)
} }
if let hir::FunctionRetTy::Return(ref ty) = decl.output { if let hir::FnRetTy::Return(ref ty) = decl.output {
check(&ty, *fty.output().skip_binder()) check(&ty, *fty.output().skip_binder())
} }
} }

View File

@ -43,7 +43,7 @@ use utils::*;
pub use utils::{get_auto_trait_and_blanket_impls, krate, register_res}; pub use utils::{get_auto_trait_and_blanket_impls, krate, register_res};
pub use self::types::FunctionRetTy::*; pub use self::types::FnRetTy::*;
pub use self::types::ItemEnum::*; pub use self::types::ItemEnum::*;
pub use self::types::SelfTy::*; pub use self::types::SelfTy::*;
pub use self::types::Type::*; pub use self::types::Type::*;
@ -1001,8 +1001,8 @@ impl<'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
} }
} }
impl Clean<FunctionRetTy> for hir::FunctionRetTy<'_> { impl Clean<FnRetTy> for hir::FnRetTy<'_> {
fn clean(&self, cx: &DocContext<'_>) -> FunctionRetTy { fn clean(&self, cx: &DocContext<'_>) -> FnRetTy {
match *self { match *self {
Self::Return(ref typ) => Return(typ.clean(cx)), Self::Return(ref typ) => Return(typ.clean(cx)),
Self::DefaultReturn(..) => DefaultReturn, Self::DefaultReturn(..) => DefaultReturn,

View File

@ -35,7 +35,7 @@ use crate::doctree;
use crate::html::item_type::ItemType; use crate::html::item_type::ItemType;
use crate::html::render::{cache, ExternalLocation}; use crate::html::render::{cache, ExternalLocation};
use self::FunctionRetTy::*; use self::FnRetTy::*;
use self::ItemEnum::*; use self::ItemEnum::*;
use self::SelfTy::*; use self::SelfTy::*;
use self::Type::*; use self::Type::*;
@ -862,7 +862,7 @@ pub struct Function {
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub struct FnDecl { pub struct FnDecl {
pub inputs: Arguments, pub inputs: Arguments,
pub output: FunctionRetTy, pub output: FnRetTy,
pub c_variadic: bool, pub c_variadic: bool,
pub attrs: Attributes, pub attrs: Attributes,
} }
@ -881,12 +881,12 @@ impl FnDecl {
/// ///
/// This function will panic if the return type does not match the expected sugaring for async /// This function will panic if the return type does not match the expected sugaring for async
/// functions. /// functions.
pub fn sugared_async_return_type(&self) -> FunctionRetTy { pub fn sugared_async_return_type(&self) -> FnRetTy {
match &self.output { match &self.output {
FunctionRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] { FnRetTy::Return(Type::ImplTrait(bounds)) => match &bounds[0] {
GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => { GenericBound::TraitBound(PolyTrait { trait_, .. }, ..) => {
let bindings = trait_.bindings().unwrap(); let bindings = trait_.bindings().unwrap();
FunctionRetTy::Return(bindings[0].ty().clone()) FnRetTy::Return(bindings[0].ty().clone())
} }
_ => panic!("unexpected desugaring of async function"), _ => panic!("unexpected desugaring of async function"),
}, },
@ -931,12 +931,12 @@ impl Argument {
} }
#[derive(Clone, PartialEq, Eq, Debug, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Hash)]
pub enum FunctionRetTy { pub enum FnRetTy {
Return(Type), Return(Type),
DefaultReturn, DefaultReturn,
} }
impl GetDefId for FunctionRetTy { impl GetDefId for FnRetTy {
fn def_id(&self) -> Option<DefId> { fn def_id(&self) -> Option<DefId> {
match *self { match *self {
Return(ref ty) => ty.def_id(), Return(ref ty) => ty.def_id(),

View File

@ -1,7 +1,7 @@
use crate::clean::auto_trait::AutoTraitFinder; use crate::clean::auto_trait::AutoTraitFinder;
use crate::clean::blanket_impl::BlanketImplFinder; use crate::clean::blanket_impl::BlanketImplFinder;
use crate::clean::{ use crate::clean::{
inline, Clean, Crate, Deprecation, ExternalCrate, FnDecl, FunctionRetTy, Generic, GenericArg, inline, Clean, Crate, Deprecation, ExternalCrate, FnDecl, FnRetTy, Generic, GenericArg,
GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemEnum, MacroKind, Path, GenericArgs, GenericBound, Generics, GetDefId, ImportSource, Item, ItemEnum, MacroKind, Path,
PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Stability, Type, TypeBinding, PathSegment, Primitive, PrimitiveType, ResolvedPath, Span, Stability, Type, TypeBinding,
TypeKind, Visibility, WherePredicate, TypeKind, Visibility, WherePredicate,
@ -273,7 +273,7 @@ pub fn get_all_types(
} }
let ret_types = match decl.output { let ret_types = match decl.output {
FunctionRetTy::Return(ref return_type) => { FnRetTy::Return(ref return_type) => {
let mut ret = get_real_types(generics, &return_type, cx, 0); let mut ret = get_real_types(generics, &return_type, cx, 0);
if ret.is_empty() { if ret.is_empty() {
ret.insert(return_type.clone()); ret.insert(return_type.clone());

View File

@ -933,7 +933,7 @@ impl clean::Arguments {
} }
} }
impl clean::FunctionRetTy { impl clean::FnRetTy {
crate fn print(&self) -> impl fmt::Display + '_ { crate fn print(&self) -> impl fmt::Display + '_ {
display_fn(move |f| match self { display_fn(move |f| match self {
clean::Return(clean::Tuple(tys)) if tys.is_empty() => Ok(()), clean::Return(clean::Tuple(tys)) if tys.is_empty() => Ok(()),

View File

@ -243,7 +243,7 @@ pub struct ParenthesizedArgs {
pub inputs: Vec<P<Ty>>, pub inputs: Vec<P<Ty>>,
/// `C` /// `C`
pub output: FunctionRetTy, pub output: FnRetTy,
} }
impl ParenthesizedArgs { impl ParenthesizedArgs {
@ -2083,7 +2083,7 @@ impl Param {
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub struct FnDecl { pub struct FnDecl {
pub inputs: Vec<Param>, pub inputs: Vec<Param>,
pub output: FunctionRetTy, pub output: FnRetTy,
} }
impl FnDecl { impl FnDecl {
@ -2168,8 +2168,7 @@ impl fmt::Debug for ImplPolarity {
} }
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)] #[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
pub enum FunctionRetTy { pub enum FnRetTy {
// FIXME(Centril): Rename to `FnRetTy` and in HIR also.
/// Returns type is not specified. /// Returns type is not specified.
/// ///
/// Functions default to `()` and closures default to inference. /// Functions default to `()` and closures default to inference.
@ -2179,11 +2178,11 @@ pub enum FunctionRetTy {
Ty(P<Ty>), Ty(P<Ty>),
} }
impl FunctionRetTy { impl FnRetTy {
pub fn span(&self) -> Span { pub fn span(&self) -> Span {
match *self { match *self {
FunctionRetTy::Default(span) => span, FnRetTy::Default(span) => span,
FunctionRetTy::Ty(ref ty) => ty.span, FnRetTy::Ty(ref ty) => ty.span,
} }
} }
} }

View File

@ -744,10 +744,10 @@ pub fn noop_visit_fn_decl<T: MutVisitor>(decl: &mut P<FnDecl>, vis: &mut T) {
noop_visit_fn_ret_ty(output, vis); noop_visit_fn_ret_ty(output, vis);
} }
pub fn noop_visit_fn_ret_ty<T: MutVisitor>(fn_ret_ty: &mut FunctionRetTy, vis: &mut T) { pub fn noop_visit_fn_ret_ty<T: MutVisitor>(fn_ret_ty: &mut FnRetTy, vis: &mut T) {
match fn_ret_ty { match fn_ret_ty {
FunctionRetTy::Default(span) => vis.visit_span(span), FnRetTy::Default(span) => vis.visit_span(span),
FunctionRetTy::Ty(ty) => vis.visit_ty(ty), FnRetTy::Ty(ty) => vis.visit_ty(ty),
} }
} }

View File

@ -215,7 +215,7 @@ pub trait Visitor<'ast>: Sized {
fn visit_vis(&mut self, vis: &'ast Visibility) { fn visit_vis(&mut self, vis: &'ast Visibility) {
walk_vis(self, vis) walk_vis(self, vis)
} }
fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FunctionRetTy) { fn visit_fn_ret_ty(&mut self, ret_ty: &'ast FnRetTy) {
walk_fn_ret_ty(self, ret_ty) walk_fn_ret_ty(self, ret_ty)
} }
fn visit_fn_header(&mut self, _header: &'ast FnHeader) { fn visit_fn_header(&mut self, _header: &'ast FnHeader) {
@ -594,8 +594,8 @@ pub fn walk_where_predicate<'a, V: Visitor<'a>>(visitor: &mut V, predicate: &'a
} }
} }
pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FunctionRetTy) { pub fn walk_fn_ret_ty<'a, V: Visitor<'a>>(visitor: &mut V, ret_ty: &'a FnRetTy) {
if let FunctionRetTy::Ty(ref output_ty) = *ret_ty { if let FnRetTy::Ty(ref output_ty) = *ret_ty {
visitor.visit_ty(output_ty) visitor.visit_ty(output_ty)
} }
} }

View File

@ -117,7 +117,7 @@ fn iter_exprs(depth: usize, f: &mut dyn FnMut(P<Expr>)) {
11 => { 11 => {
let decl = P(FnDecl { let decl = P(FnDecl {
inputs: vec![], inputs: vec![],
output: FunctionRetTy::Default(DUMMY_SP), output: FnRetTy::Default(DUMMY_SP),
}); });
iter_exprs(depth - 1, &mut |e| g( iter_exprs(depth - 1, &mut |e| g(
ExprKind::Closure(CaptureBy::Value, ExprKind::Closure(CaptureBy::Value,