mirror of
https://github.com/rust-lang/rust.git
synced 2025-05-03 13:37:37 +00:00
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:
commit
75b98fbe77
@ -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].
|
||||||
|
@ -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
|
||||||
///
|
///
|
||||||
|
@ -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,
|
||||||
|
@ -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>"
|
||||||
|
@ -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);
|
||||||
|
@ -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));
|
||||||
|
@ -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 {
|
||||||
|
@ -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("->");
|
||||||
|
@ -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),
|
||||||
|
@ -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 };
|
||||||
|
@ -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)));
|
||||||
|
@ -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,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -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));
|
||||||
|
|
||||||
|
@ -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>
|
||||||
|
@ -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 })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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 = ¯o_tts.trees().collect::<Vec<_>>();
|
let tts = ¯o_tts.trees().collect::<Vec<_>>();
|
||||||
match &tts[..] {
|
match &tts[..] {
|
||||||
|
@ -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,
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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 {
|
||||||
|
@ -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`.
|
||||||
|
@ -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;
|
||||||
|
@ -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,
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -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" },
|
||||||
),
|
),
|
||||||
|
@ -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>")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)?
|
||||||
}
|
}
|
||||||
|
@ -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()?;
|
||||||
|
@ -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())
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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
|
||||||
{
|
{
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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);
|
||||||
|
@ -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 {
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
|
@ -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())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
@ -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(),
|
||||||
|
@ -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());
|
||||||
|
@ -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(()),
|
||||||
|
@ -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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
Loading…
Reference in New Issue
Block a user