Skip to content

Commit

Permalink
Auto merge of rust-lang#16388 - Veykril:fn-abi, r=Veykril
Browse files Browse the repository at this point in the history
internal: Record FnAbi

This unfortunately breaks our lub coercions, so will need to look into fixing that first, though I am not sure what is going wrong where...

Stubbed some stuff out for the time being.
  • Loading branch information
bors committed Jan 19, 2024
2 parents 03d4a6d + 46e3831 commit 04edfa1
Show file tree
Hide file tree
Showing 20 changed files with 329 additions and 115 deletions.
22 changes: 18 additions & 4 deletions crates/hir-def/src/hir/type_ref.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ use hir_expand::{
AstId,
};
use intern::Interned;
use syntax::ast::{self, HasName};
use syntax::ast::{self, HasName, IsString};

use crate::{
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
Expand Down Expand Up @@ -120,7 +120,12 @@ pub enum TypeRef {
Array(Box<TypeRef>, ConstRef),
Slice(Box<TypeRef>),
/// A fn pointer. Last element of the vector is the return type.
Fn(Vec<(Option<Name>, TypeRef)>, bool /*varargs*/, bool /*is_unsafe*/),
Fn(
Vec<(Option<Name>, TypeRef)>,
bool, /*varargs*/
bool, /*is_unsafe*/
Option<Interned<str>>, /* abi */
),
ImplTrait(Vec<Interned<TypeBound>>),
DynTrait(Vec<Interned<TypeBound>>),
Macro(AstId<ast::MacroCall>),
Expand Down Expand Up @@ -225,8 +230,17 @@ impl TypeRef {
} else {
Vec::new()
};
fn lower_abi(abi: ast::Abi) -> Interned<str> {
match abi.abi_string() {
Some(tok) => Interned::new_str(tok.text_without_quotes()),
// `extern` default to be `extern "C"`.
_ => Interned::new_str("C"),
}
}

let abi = inner.abi().map(lower_abi);
params.push((None, ret_ty));
TypeRef::Fn(params, is_varargs, inner.unsafe_token().is_some())
TypeRef::Fn(params, is_varargs, inner.unsafe_token().is_some(), abi)
}
// for types are close enough for our purposes to the inner type for now...
ast::Type::ForType(inner) => TypeRef::from_ast_opt(ctx, inner.ty()),
Expand Down Expand Up @@ -260,7 +274,7 @@ impl TypeRef {
fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) {
f(type_ref);
match type_ref {
TypeRef::Fn(params, _, _) => {
TypeRef::Fn(params, _, _, _) => {
params.iter().for_each(|(_, param_type)| go(param_type, f))
}
TypeRef::Tuple(types) => types.iter().for_each(|t| go(t, f)),
Expand Down
16 changes: 5 additions & 11 deletions crates/hir-def/src/item_tree/lower.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
use std::collections::hash_map::Entry;

use hir_expand::{ast_id_map::AstIdMap, span_map::SpanMapRef, HirFileId};
use syntax::ast::{self, HasModuleItem, HasTypeBounds};
use syntax::ast::{self, HasModuleItem, HasTypeBounds, IsString};

use crate::{
generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance},
Expand Down Expand Up @@ -721,16 +721,10 @@ enum HasImplicitSelf {
}

fn lower_abi(abi: ast::Abi) -> Interned<str> {
// FIXME: Abi::abi() -> Option<SyntaxToken>?
match abi.syntax().last_token() {
Some(tok) if tok.kind() == SyntaxKind::STRING => {
// FIXME: Better way to unescape?
Interned::new_str(tok.text().trim_matches('"'))
}
_ => {
// `extern` default to be `extern "C"`.
Interned::new_str("C")
}
match abi.abi_string() {
Some(tok) => Interned::new_str(tok.text_without_quotes()),
// `extern` default to be `extern "C"`.
_ => Interned::new_str("C"),
}
}

Expand Down
7 changes: 6 additions & 1 deletion crates/hir-def/src/pretty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,12 +192,17 @@ pub(crate) fn print_type_ref(
print_type_ref(db, elem, buf)?;
write!(buf, "]")?;
}
TypeRef::Fn(args_and_ret, varargs, is_unsafe) => {
TypeRef::Fn(args_and_ret, varargs, is_unsafe, abi) => {
let ((_, return_type), args) =
args_and_ret.split_last().expect("TypeRef::Fn is missing return type");
if *is_unsafe {
write!(buf, "unsafe ")?;
}
if let Some(abi) = abi {
buf.write_str("extern ")?;
buf.write_str(abi)?;
buf.write_char(' ')?;
}
write!(buf, "fn(")?;
for (i, (_, typeref)) in args.iter().enumerate() {
if i != 0 {
Expand Down
6 changes: 5 additions & 1 deletion crates/hir-ty/src/chalk_db.rs
Original file line number Diff line number Diff line change
Expand Up @@ -819,7 +819,11 @@ pub(crate) fn fn_def_datum_query(
};
let datum = FnDefDatum {
id: fn_def_id,
sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs },
sig: chalk_ir::FnSig {
abi: sig.abi,
safety: chalk_ir::Safety::Safe,
variadic: sig.is_varargs,
},
binders: chalk_ir::Binders::new(binders, bound),
};
Arc::new(datum)
Expand Down
6 changes: 1 addition & 5 deletions crates/hir-ty/src/chalk_ext.rs
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,7 @@ impl TyExt for Ty {
fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
match self.kind(Interner) {
TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
TyKind::FnDef(def, parameters) => {
let callable_def = db.lookup_intern_callable_def((*def).into());
let sig = db.callable_item_signature(callable_def);
Some(sig.substitute(Interner, parameters))
}
TyKind::FnDef(def, parameters) => Some(CallableSig::from_def(db, *def, parameters)),
TyKind::Closure(.., substs) => ClosureSubst(substs).sig_ty().callable_sig(db),
_ => None,
}
Expand Down
39 changes: 32 additions & 7 deletions crates/hir-ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use std::{
};

use base_db::CrateId;
use chalk_ir::{BoundVar, TyKind};
use chalk_ir::{BoundVar, Safety, TyKind};
use hir_def::{
data::adt::VariantData,
db::DefDatabase,
Expand Down Expand Up @@ -41,7 +41,7 @@ use crate::{
primitive, to_assoc_type_id,
utils::{self, detect_variant_from_bytes, generics, ClosureSubst},
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Const, ConstScalar, ConstValue,
DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives,
DomainGoal, FnAbi, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives,
MemoryMap, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Scalar,
Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyExt, WhereClause,
};
Expand Down Expand Up @@ -879,16 +879,27 @@ impl HirDisplay for Ty {
// function pointer type.
return sig.hir_fmt(f);
}
if let Safety::Unsafe = sig.safety {
write!(f, "unsafe ")?;
}
if !matches!(sig.abi, FnAbi::Rust) {
f.write_str("extern \"")?;
f.write_str(sig.abi.as_str())?;
f.write_str("\" ")?;
}

f.start_location_link(def.into());
match def {
CallableDefId::FunctionId(ff) => {
write!(f, "fn {}", db.function_data(ff).name.display(f.db.upcast()))?
write!(f, "fn ")?;
f.start_location_link(def.into());
write!(f, "{}", db.function_data(ff).name.display(f.db.upcast()))?
}
CallableDefId::StructId(s) => {
f.start_location_link(def.into());
write!(f, "{}", db.struct_data(s).name.display(f.db.upcast()))?
}
CallableDefId::EnumVariantId(e) => {
f.start_location_link(def.into());
write!(f, "{}", db.enum_variant_data(e).name.display(f.db.upcast()))?
}
};
Expand Down Expand Up @@ -1316,9 +1327,19 @@ fn hir_fmt_generics(

impl HirDisplay for CallableSig {
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
let CallableSig { params_and_return: _, is_varargs, safety, abi: _ } = *self;
if let Safety::Unsafe = safety {
write!(f, "unsafe ")?;
}
// FIXME: Enable this when the FIXME on FnAbi regarding PartialEq is fixed.
// if !matches!(abi, FnAbi::Rust) {
// f.write_str("extern \"")?;
// f.write_str(abi.as_str())?;
// f.write_str("\" ")?;
// }
write!(f, "fn(")?;
f.write_joined(self.params(), ", ")?;
if self.is_varargs {
if is_varargs {
if self.params().is_empty() {
write!(f, "...")?;
} else {
Expand Down Expand Up @@ -1683,11 +1704,15 @@ impl HirDisplay for TypeRef {
inner.hir_fmt(f)?;
write!(f, "]")?;
}
&TypeRef::Fn(ref parameters, is_varargs, is_unsafe) => {
// FIXME: Function pointer qualifiers.
&TypeRef::Fn(ref parameters, is_varargs, is_unsafe, ref abi) => {
if is_unsafe {
write!(f, "unsafe ")?;
}
if let Some(abi) = abi {
f.write_str("extern \"")?;
f.write_str(abi)?;
f.write_str("\" ")?;
}
write!(f, "fn(")?;
if let Some(((_, return_type), function_parameters)) = parameters.split_last() {
for index in 0..function_parameters.len() {
Expand Down
6 changes: 3 additions & 3 deletions crates/hir-ty/src/infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1453,10 +1453,10 @@ impl Expectation {
match self {
Expectation::HasType(ety) => {
let ety = table.resolve_ty_shallow(ety);
if !ety.is_ty_var() {
Expectation::HasType(ety)
} else {
if ety.is_ty_var() {
Expectation::None
} else {
Expectation::HasType(ety)
}
}
Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()),
Expand Down
10 changes: 7 additions & 3 deletions crates/hir-ty/src/infer/closure.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@ use crate::{
static_lifetime, to_chalk_trait_id,
traits::FnTrait,
utils::{self, generics, Generics},
Adjust, Adjustment, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy, FnPointer, FnSig,
Interner, Substitution, Ty, TyExt,
Adjust, Adjustment, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy, FnAbi, FnPointer,
FnSig, Interner, Substitution, Ty, TyExt,
};

use super::{Expectation, InferenceContext};
Expand Down Expand Up @@ -98,7 +98,11 @@ impl InferenceContext<'_> {
cov_mark::hit!(dyn_fn_param_informs_call_site_closure_signature);
return Some(FnPointer {
num_binders: bound.len(Interner),
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
sig: FnSig {
abi: FnAbi::RustCall,
safety: chalk_ir::Safety::Safe,
variadic: false,
},
substitution: FnSubst(Substitution::from_iter(Interner, sig_tys)),
});
}
Expand Down
4 changes: 2 additions & 2 deletions crates/hir-ty/src/infer/coerce.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ use crate::{
},
static_lifetime,
utils::ClosureSubst,
Canonical, DomainGoal, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution,
Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution,
Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
};

Expand Down Expand Up @@ -691,7 +691,7 @@ fn coerce_closure_fn_ty(closure_substs: &Substitution, safety: chalk_ir::Safety)
match closure_sig.kind(Interner) {
TyKind::Function(fn_ty) => TyKind::Function(FnPointer {
num_binders: fn_ty.num_binders,
sig: FnSig { safety, ..fn_ty.sig },
sig: FnSig { safety, abi: FnAbi::Rust, variadic: fn_ty.sig.variadic },
substitution: fn_ty.substitution.clone(),
})
.intern(Interner),
Expand Down
12 changes: 8 additions & 4 deletions crates/hir-ty/src/infer/expr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,9 @@ use crate::{
static_lifetime, to_chalk_trait_id,
traits::FnTrait,
utils::{generics, Generics},
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, FnPointer, FnSig, FnSubst,
Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt,
TyKind,
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, FnAbi, FnPointer, FnSig,
FnSubst, Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder,
TyExt, TyKind,
};

use super::{
Expand Down Expand Up @@ -224,7 +224,11 @@ impl InferenceContext<'_> {

let sig_ty = TyKind::Function(FnPointer {
num_binders: 0,
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
sig: FnSig {
abi: FnAbi::RustCall,
safety: chalk_ir::Safety::Safe,
variadic: false,
},
substitution: FnSubst(
Substitution::from_iter(Interner, sig_tys.iter().cloned())
.shifted_in(Interner),
Expand Down
6 changes: 3 additions & 3 deletions crates/hir-ty/src/interner.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@

use crate::{
chalk_db, tls, AliasTy, CanonicalVarKind, CanonicalVarKinds, ClosureId, Const, ConstData,
ConstScalar, Constraint, Constraints, FnDefId, GenericArg, GenericArgData, Goal, GoalData,
Goals, InEnvironment, Lifetime, LifetimeData, OpaqueTy, OpaqueTyId, ProgramClause,
ConstScalar, Constraint, Constraints, FnAbi, FnDefId, GenericArg, GenericArgData, Goal,
GoalData, Goals, InEnvironment, Lifetime, LifetimeData, OpaqueTy, OpaqueTyId, ProgramClause,
ProgramClauseData, ProgramClauses, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses,
Substitution, Ty, TyData, TyKind, VariableKind, VariableKinds,
};
Expand Down Expand Up @@ -71,7 +71,7 @@ impl chalk_ir::interner::Interner for Interner {
type DefId = InternId;
type InternedAdtId = hir_def::AdtId;
type Identifier = TypeAliasId;
type FnAbi = ();
type FnAbi = FnAbi;

fn debug_adt_id(
type_kind_id: chalk_db::AdtId,
Expand Down
Loading

0 comments on commit 04edfa1

Please sign in to comment.