Record asyncness span in HIR

This commit is contained in:
Michael Goulet 2023-09-14 22:38:07 +00:00
parent 0fd7ce99b0
commit 087a571e70
22 changed files with 78 additions and 54 deletions

View File

@ -1308,7 +1308,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
fn lower_asyncness(&mut self, a: Async) -> hir::IsAsync {
match a {
Async::Yes { .. } => hir::IsAsync::Async,
Async::Yes { span, .. } => hir::IsAsync::Async(span),
Async::No => hir::IsAsync::NotAsync,
}
}

View File

@ -302,7 +302,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
if free_region.bound_region.is_named() {
// A named region that is actually named.
Some(RegionName { name, source: RegionNameSource::NamedFreeRegion(span) })
} else if let hir::IsAsync::Async = tcx.asyncness(self.mir_hir_id().owner) {
} else if tcx.asyncness(self.mir_hir_id().owner).is_async() {
// If we spuriously thought that the region is named, we should let the
// system generate a true name for error messages. Currently this can
// happen if we have an elided name in an async fn for example: the

View File

@ -2853,13 +2853,13 @@ impl ImplicitSelfKind {
#[derive(Copy, Clone, PartialEq, Eq, Encodable, Decodable, Debug)]
#[derive(HashStable_Generic)]
pub enum IsAsync {
Async,
Async(Span),
NotAsync,
}
impl IsAsync {
pub fn is_async(self) -> bool {
self == IsAsync::Async
matches!(self, IsAsync::Async(_))
}
}
@ -3296,7 +3296,7 @@ pub struct FnHeader {
impl FnHeader {
pub fn is_async(&self) -> bool {
matches!(&self.asyncness, IsAsync::Async)
matches!(&self.asyncness, IsAsync::Async(_))
}
pub fn is_const(&self) -> bool {
@ -4091,10 +4091,10 @@ mod size_asserts {
static_assert_size!(GenericBound<'_>, 48);
static_assert_size!(Generics<'_>, 56);
static_assert_size!(Impl<'_>, 80);
static_assert_size!(ImplItem<'_>, 80);
static_assert_size!(ImplItemKind<'_>, 32);
static_assert_size!(Item<'_>, 80);
static_assert_size!(ItemKind<'_>, 48);
static_assert_size!(ImplItem<'_>, 88);
static_assert_size!(ImplItemKind<'_>, 40);
static_assert_size!(Item<'_>, 88);
static_assert_size!(ItemKind<'_>, 56);
static_assert_size!(Local<'_>, 64);
static_assert_size!(Param<'_>, 32);
static_assert_size!(Pat<'_>, 72);
@ -4105,8 +4105,8 @@ mod size_asserts {
static_assert_size!(Res, 12);
static_assert_size!(Stmt<'_>, 32);
static_assert_size!(StmtKind<'_>, 16);
static_assert_size!(TraitItem<'_>, 80);
static_assert_size!(TraitItemKind<'_>, 40);
static_assert_size!(TraitItem<'_>, 88);
static_assert_size!(TraitItemKind<'_>, 48);
static_assert_size!(Ty<'_>, 48);
static_assert_size!(TyKind<'_>, 32);
// tidy-alphabetical-end

View File

@ -595,7 +595,7 @@ fn compare_asyncness<'tcx>(
trait_m: ty::AssocItem,
delay: bool,
) -> Result<(), ErrorGuaranteed> {
if tcx.asyncness(trait_m.def_id) == hir::IsAsync::Async {
if tcx.asyncness(trait_m.def_id).is_async() {
match tcx.fn_sig(impl_m.def_id).skip_binder().skip_binder().output().kind() {
ty::Alias(ty::Opaque, ..) => {
// allow both `async fn foo()` and `fn foo() -> impl Future`

View File

@ -112,7 +112,7 @@ fn check_main_fn_ty(tcx: TyCtxt<'_>, main_def_id: DefId) {
}
let main_asyncness = tcx.asyncness(main_def_id);
if let hir::IsAsync::Async = main_asyncness {
if main_asyncness.is_async() {
let asyncness_span = main_fn_asyncness_span(tcx, main_def_id);
tcx.sess.emit_err(errors::MainFunctionAsync { span: main_span, asyncness: asyncness_span });
error = true;
@ -212,7 +212,7 @@ fn check_start_fn_ty(tcx: TyCtxt<'_>, start_def_id: DefId) {
});
error = true;
}
if let hir::IsAsync::Async = sig.header.asyncness {
if sig.header.asyncness.is_async() {
let span = tcx.def_span(it.owner_id);
tcx.sess.emit_err(errors::StartAsync { span: span });
error = true;

View File

@ -1213,7 +1213,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
&& let Some(generics) = self.tcx.hir().get_generics(self.tcx.local_parent(param_id))
&& let Some(param) = generics.params.iter().find(|p| p.def_id == param_id)
&& param.is_elided_lifetime()
&& let hir::IsAsync::NotAsync = self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id)
&& !self.tcx.asyncness(lifetime_ref.hir_id.owner.def_id).is_async()
&& !self.tcx.features().anonymous_lifetime_in_impl_trait
{
let mut diag = rustc_session::parse::feature_err(

View File

@ -2304,7 +2304,7 @@ impl<'a> State<'a> {
match header.asyncness {
hir::IsAsync::NotAsync => {}
hir::IsAsync::Async => self.word_nbsp("async"),
hir::IsAsync::Async(_) => self.word_nbsp("async"),
}
self.print_unsafety(header.unsafety);

View File

@ -987,10 +987,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let bound_vars = self.tcx.late_bound_vars(fn_id);
let ty = self.tcx.erase_late_bound_regions(Binder::bind_with_vars(ty, bound_vars));
let ty = match self.tcx.asyncness(fn_id.owner) {
hir::IsAsync::Async => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
ty::Asyncness::Yes => self.get_impl_future_output_ty(ty).unwrap_or_else(|| {
span_bug!(fn_decl.output.span(), "failed to get output type of async function")
}),
hir::IsAsync::NotAsync => ty,
ty::Asyncness::No => ty,
};
let ty = self.normalize(expr.span, ty);
if self.can_coerce(found, ty) {

View File

@ -41,7 +41,6 @@ use crate::{
},
EarlyContext, EarlyLintPass, LateContext, LateLintPass, Level, LintContext,
};
use hir::IsAsync;
use rustc_ast::attr;
use rustc_ast::tokenstream::{TokenStream, TokenTree};
use rustc_ast::visit::{FnCtxt, FnKind};
@ -1294,7 +1293,7 @@ impl<'tcx> LateLintPass<'tcx> for UngatedAsyncFnTrackCaller {
span: Span,
def_id: LocalDefId,
) {
if fn_kind.asyncness() == IsAsync::Async
if fn_kind.asyncness().is_async()
&& !cx.tcx.features().async_fn_track_caller
// Now, check if the function has the `#[track_caller]` attribute
&& let Some(attr) = cx.tcx.get_attr(def_id, sym::track_caller)

View File

@ -439,7 +439,7 @@ define_tables! {
coerce_unsized_info: Table<DefIndex, LazyValue<ty::adjustment::CoerceUnsizedInfo>>,
mir_const_qualif: Table<DefIndex, LazyValue<mir::ConstQualifs>>,
rendered_const: Table<DefIndex, LazyValue<String>>,
asyncness: Table<DefIndex, hir::IsAsync>,
asyncness: Table<DefIndex, ty::Asyncness>,
fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
generator_kind: Table<DefIndex, LazyValue<hir::GeneratorKind>>,
trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,

View File

@ -205,9 +205,9 @@ fixed_size_enum! {
}
fixed_size_enum! {
hir::IsAsync {
( NotAsync )
( Async )
ty::Asyncness {
( Yes )
( No )
}
}

View File

@ -265,6 +265,7 @@ trivial! {
rustc_middle::ty::adjustment::CoerceUnsizedInfo,
rustc_middle::ty::AssocItem,
rustc_middle::ty::AssocItemContainer,
rustc_middle::ty::Asyncness,
rustc_middle::ty::BoundVariableKind,
rustc_middle::ty::DeducedParamAttrs,
rustc_middle::ty::Destructor,

View File

@ -731,7 +731,7 @@ rustc_queries! {
separate_provide_extern
}
query asyncness(key: DefId) -> hir::IsAsync {
query asyncness(key: DefId) -> ty::Asyncness {
desc { |tcx| "checking if the function is async: `{}`", tcx.def_path_str(key) }
separate_provide_extern
}

View File

@ -280,6 +280,19 @@ impl fmt::Display for ImplPolarity {
}
}
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable, HashStable, Debug)]
#[derive(TypeFoldable, TypeVisitable)]
pub enum Asyncness {
Yes,
No,
}
impl Asyncness {
pub fn is_async(self) -> bool {
matches!(self, Asyncness::Yes)
}
}
#[derive(Clone, Debug, PartialEq, Eq, Copy, Hash, Encodable, Decodable, HashStable)]
pub enum Visibility<Id = LocalDefId> {
/// Visible everywhere (including in other crates).

View File

@ -62,6 +62,7 @@ trivially_parameterized_over_tcx! {
crate::middle::resolve_bound_vars::ObjectLifetimeDefault,
crate::mir::ConstQualifs,
ty::AssocItemContainer,
ty::Asyncness,
ty::DeducedParamAttrs,
ty::Generics,
ty::ImplPolarity,

View File

@ -104,7 +104,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
hir::Node::Item(hir::Item { kind: hir::ItemKind::Fn(sig, _, body_id), .. }) => {
self.describe_generator(*body_id).or_else(|| {
Some(match sig.header {
hir::FnHeader { asyncness: hir::IsAsync::Async, .. } => "an async function",
hir::FnHeader { asyncness: hir::IsAsync::Async(_), .. } => {
"an async function"
}
_ => "a function",
})
})
@ -118,7 +120,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
..
}) => self.describe_generator(*body_id).or_else(|| {
Some(match sig.header {
hir::FnHeader { asyncness: hir::IsAsync::Async, .. } => "an async method",
hir::FnHeader { asyncness: hir::IsAsync::Async(_), .. } => "an async method",
_ => "a method",
})
}),

View File

@ -296,9 +296,12 @@ fn issue33140_self_ty(tcx: TyCtxt<'_>, def_id: DefId) -> Option<EarlyBinder<Ty<'
}
/// Check if a function is async.
fn asyncness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> hir::IsAsync {
fn asyncness(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Asyncness {
let node = tcx.hir().get_by_def_id(def_id);
node.fn_sig().map_or(hir::IsAsync::NotAsync, |sig| sig.header.asyncness)
node.fn_sig().map_or(ty::Asyncness::No, |sig| match sig.header.asyncness {
hir::IsAsync::Async(_) => ty::Asyncness::Yes,
hir::IsAsync::NotAsync => ty::Asyncness::No,
})
}
fn unsizing_params_for_adt<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId) -> BitSet<u32> {

View File

@ -31,7 +31,7 @@ use rustc_resolve::rustdoc::{
use rustc_session::Session;
use rustc_span::hygiene::MacroKind;
use rustc_span::symbol::{kw, sym, Ident, Symbol};
use rustc_span::{self, FileName, Loc};
use rustc_span::{self, FileName, Loc, DUMMY_SP};
use rustc_target::abi::VariantIdx;
use rustc_target::spec::abi::Abi;
@ -622,7 +622,7 @@ impl Item {
fn build_fn_header(
def_id: DefId,
tcx: TyCtxt<'_>,
asyncness: hir::IsAsync,
asyncness: ty::Asyncness,
) -> hir::FnHeader {
let sig = tcx.fn_sig(def_id).skip_binder();
let constness =
@ -631,6 +631,10 @@ impl Item {
} else {
hir::Constness::NotConst
};
let asyncness = match asyncness {
ty::Asyncness::Yes => hir::IsAsync::Async(DUMMY_SP),
ty::Asyncness::No => hir::IsAsync::NotAsync,
};
hir::FnHeader { unsafety: sig.unsafety(), abi: sig.abi(), constness, asyncness }
}
let header = match *self.kind {

View File

@ -1599,7 +1599,7 @@ impl PrintWithSpace for hir::Unsafety {
impl PrintWithSpace for hir::IsAsync {
fn print_with_space(&self) -> &str {
match self {
hir::IsAsync::Async => "async ",
hir::IsAsync::Async(_) => "async ",
hir::IsAsync::NotAsync => "",
}
}

View File

@ -10,6 +10,7 @@ use rustc_hir::intravisit::{Visitor as HirVisitor, Visitor};
use rustc_lint::{LateContext, LateLintPass};
use rustc_middle::hir::nested_filter;
use rustc_middle::lint::in_external_macro;
use rustc_middle::ty;
use rustc_session::{declare_lint_pass, declare_tool_lint};
declare_clippy_lint! {
@ -84,7 +85,7 @@ fn find_innermost_closure<'tcx>(
cx: &LateContext<'tcx>,
mut expr: &'tcx hir::Expr<'tcx>,
mut steps: usize,
) -> Option<(&'tcx hir::Expr<'tcx>, &'tcx hir::FnDecl<'tcx>, hir::IsAsync)> {
) -> Option<(&'tcx hir::Expr<'tcx>, &'tcx hir::FnDecl<'tcx>, ty::Asyncness)> {
let mut data = None;
while let hir::ExprKind::Closure(closure) = expr.kind
@ -98,9 +99,9 @@ fn find_innermost_closure<'tcx>(
{
expr = body.value;
data = Some((body.value, closure.fn_decl, if is_async_closure(body) {
hir::IsAsync::Async
ty::Asyncness::Yes
} else {
hir::IsAsync::NotAsync
ty::Asyncness::No
}));
steps -= 1;
}

View File

@ -90,7 +90,7 @@ use rustc_hir::intravisit::{walk_expr, FnKind, Visitor};
use rustc_hir::LangItem::{OptionNone, OptionSome, ResultErr, ResultOk};
use rustc_hir::{
self as hir, def, Arm, ArrayLen, BindingAnnotation, Block, BlockCheckMode, Body, Closure, Destination, Expr,
ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, IsAsync, Item,
ExprField, ExprKind, FnDecl, FnRetTy, GenericArgs, HirId, Impl, ImplItem, ImplItemKind, ImplItemRef, Item,
ItemKind, LangItem, Local, MatchSource, Mutability, Node, OwnerId, Param, Pat, PatKind, Path, PathSegment, PrimTy,
QPath, Stmt, StmtKind, TraitItem, TraitItemKind, TraitItemRef, TraitRef, TyKind, UnOp,
};
@ -1958,8 +1958,8 @@ pub fn if_sequence<'tcx>(mut expr: &'tcx Expr<'tcx>) -> (Vec<&'tcx Expr<'tcx>>,
/// Checks if the given function kind is an async function.
pub fn is_async_fn(kind: FnKind<'_>) -> bool {
match kind {
FnKind::ItemFn(_, _, header) => header.asyncness == IsAsync::Async,
FnKind::Method(_, sig) => sig.header.asyncness == IsAsync::Async,
FnKind::ItemFn(_, _, header) => header.asyncness .is_async(),
FnKind::Method(_, sig) => sig.header.asyncness.is_async(),
FnKind::Closure => false,
}
}

View File

@ -146,33 +146,33 @@ hir-stats - Trait 192 ( 2.1%) 4
hir-stats WherePredicate 192 ( 2.1%) 3 64
hir-stats - BoundPredicate 192 ( 2.1%) 3
hir-stats Block 288 ( 3.2%) 6 48
hir-stats Pat 360 ( 4.0%) 5 72
hir-stats Pat 360 ( 3.9%) 5 72
hir-stats - Wild 72 ( 0.8%) 1
hir-stats - Struct 72 ( 0.8%) 1
hir-stats - Binding 216 ( 2.4%) 3
hir-stats GenericParam 400 ( 4.4%) 5 80
hir-stats Generics 560 ( 6.2%) 10 56
hir-stats Ty 720 ( 8.0%) 15 48
hir-stats Generics 560 ( 6.1%) 10 56
hir-stats Ty 720 ( 7.9%) 15 48
hir-stats - Ptr 48 ( 0.5%) 1
hir-stats - Ref 48 ( 0.5%) 1
hir-stats - Path 624 ( 6.9%) 13
hir-stats Expr 768 ( 8.5%) 12 64
hir-stats - Path 624 ( 6.8%) 13
hir-stats Expr 768 ( 8.4%) 12 64
hir-stats - Path 64 ( 0.7%) 1
hir-stats - Struct 64 ( 0.7%) 1
hir-stats - Match 64 ( 0.7%) 1
hir-stats - InlineAsm 64 ( 0.7%) 1
hir-stats - Lit 128 ( 1.4%) 2
hir-stats - Block 384 ( 4.2%) 6
hir-stats Item 880 ( 9.7%) 11 80
hir-stats - Trait 80 ( 0.9%) 1
hir-stats - Enum 80 ( 0.9%) 1
hir-stats - ExternCrate 80 ( 0.9%) 1
hir-stats - ForeignMod 80 ( 0.9%) 1
hir-stats - Impl 80 ( 0.9%) 1
hir-stats - Fn 160 ( 1.8%) 2
hir-stats - Use 320 ( 3.5%) 4
hir-stats Path 1_240 (13.7%) 31 40
hir-stats PathSegment 1_920 (21.2%) 40 48
hir-stats Item 968 (10.6%) 11 88
hir-stats - Trait 88 ( 1.0%) 1
hir-stats - Enum 88 ( 1.0%) 1
hir-stats - ExternCrate 88 ( 1.0%) 1
hir-stats - ForeignMod 88 ( 1.0%) 1
hir-stats - Impl 88 ( 1.0%) 1
hir-stats - Fn 176 ( 1.9%) 2
hir-stats - Use 352 ( 3.9%) 4
hir-stats Path 1_240 (13.6%) 31 40
hir-stats PathSegment 1_920 (21.0%) 40 48
hir-stats ----------------------------------------------------------------
hir-stats Total 9_048
hir-stats Total 9_136
hir-stats