Skip to content

Commit 04edfa1

Browse files
committed
Auto merge of rust-lang#16388 - Veykril:fn-abi, r=Veykril
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.
2 parents 03d4a6d + 46e3831 commit 04edfa1

20 files changed

+329
-115
lines changed

crates/hir-def/src/hir/type_ref.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ use hir_expand::{
1010
AstId,
1111
};
1212
use intern::Interned;
13-
use syntax::ast::{self, HasName};
13+
use syntax::ast::{self, HasName, IsString};
1414

1515
use crate::{
1616
builtin_type::{BuiltinInt, BuiltinType, BuiltinUint},
@@ -120,7 +120,12 @@ pub enum TypeRef {
120120
Array(Box<TypeRef>, ConstRef),
121121
Slice(Box<TypeRef>),
122122
/// A fn pointer. Last element of the vector is the return type.
123-
Fn(Vec<(Option<Name>, TypeRef)>, bool /*varargs*/, bool /*is_unsafe*/),
123+
Fn(
124+
Vec<(Option<Name>, TypeRef)>,
125+
bool, /*varargs*/
126+
bool, /*is_unsafe*/
127+
Option<Interned<str>>, /* abi */
128+
),
124129
ImplTrait(Vec<Interned<TypeBound>>),
125130
DynTrait(Vec<Interned<TypeBound>>),
126131
Macro(AstId<ast::MacroCall>),
@@ -225,8 +230,17 @@ impl TypeRef {
225230
} else {
226231
Vec::new()
227232
};
233+
fn lower_abi(abi: ast::Abi) -> Interned<str> {
234+
match abi.abi_string() {
235+
Some(tok) => Interned::new_str(tok.text_without_quotes()),
236+
// `extern` default to be `extern "C"`.
237+
_ => Interned::new_str("C"),
238+
}
239+
}
240+
241+
let abi = inner.abi().map(lower_abi);
228242
params.push((None, ret_ty));
229-
TypeRef::Fn(params, is_varargs, inner.unsafe_token().is_some())
243+
TypeRef::Fn(params, is_varargs, inner.unsafe_token().is_some(), abi)
230244
}
231245
// for types are close enough for our purposes to the inner type for now...
232246
ast::Type::ForType(inner) => TypeRef::from_ast_opt(ctx, inner.ty()),
@@ -260,7 +274,7 @@ impl TypeRef {
260274
fn go(type_ref: &TypeRef, f: &mut impl FnMut(&TypeRef)) {
261275
f(type_ref);
262276
match type_ref {
263-
TypeRef::Fn(params, _, _) => {
277+
TypeRef::Fn(params, _, _, _) => {
264278
params.iter().for_each(|(_, param_type)| go(param_type, f))
265279
}
266280
TypeRef::Tuple(types) => types.iter().for_each(|t| go(t, f)),

crates/hir-def/src/item_tree/lower.rs

+5-11
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
use std::collections::hash_map::Entry;
44

55
use hir_expand::{ast_id_map::AstIdMap, span_map::SpanMapRef, HirFileId};
6-
use syntax::ast::{self, HasModuleItem, HasTypeBounds};
6+
use syntax::ast::{self, HasModuleItem, HasTypeBounds, IsString};
77

88
use crate::{
99
generics::{GenericParams, GenericParamsCollector, TypeParamData, TypeParamProvenance},
@@ -721,16 +721,10 @@ enum HasImplicitSelf {
721721
}
722722

723723
fn lower_abi(abi: ast::Abi) -> Interned<str> {
724-
// FIXME: Abi::abi() -> Option<SyntaxToken>?
725-
match abi.syntax().last_token() {
726-
Some(tok) if tok.kind() == SyntaxKind::STRING => {
727-
// FIXME: Better way to unescape?
728-
Interned::new_str(tok.text().trim_matches('"'))
729-
}
730-
_ => {
731-
// `extern` default to be `extern "C"`.
732-
Interned::new_str("C")
733-
}
724+
match abi.abi_string() {
725+
Some(tok) => Interned::new_str(tok.text_without_quotes()),
726+
// `extern` default to be `extern "C"`.
727+
_ => Interned::new_str("C"),
734728
}
735729
}
736730

crates/hir-def/src/pretty.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -192,12 +192,17 @@ pub(crate) fn print_type_ref(
192192
print_type_ref(db, elem, buf)?;
193193
write!(buf, "]")?;
194194
}
195-
TypeRef::Fn(args_and_ret, varargs, is_unsafe) => {
195+
TypeRef::Fn(args_and_ret, varargs, is_unsafe, abi) => {
196196
let ((_, return_type), args) =
197197
args_and_ret.split_last().expect("TypeRef::Fn is missing return type");
198198
if *is_unsafe {
199199
write!(buf, "unsafe ")?;
200200
}
201+
if let Some(abi) = abi {
202+
buf.write_str("extern ")?;
203+
buf.write_str(abi)?;
204+
buf.write_char(' ')?;
205+
}
201206
write!(buf, "fn(")?;
202207
for (i, (_, typeref)) in args.iter().enumerate() {
203208
if i != 0 {

crates/hir-ty/src/chalk_db.rs

+5-1
Original file line numberDiff line numberDiff line change
@@ -819,7 +819,11 @@ pub(crate) fn fn_def_datum_query(
819819
};
820820
let datum = FnDefDatum {
821821
id: fn_def_id,
822-
sig: chalk_ir::FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: sig.is_varargs },
822+
sig: chalk_ir::FnSig {
823+
abi: sig.abi,
824+
safety: chalk_ir::Safety::Safe,
825+
variadic: sig.is_varargs,
826+
},
823827
binders: chalk_ir::Binders::new(binders, bound),
824828
};
825829
Arc::new(datum)

crates/hir-ty/src/chalk_ext.rs

+1-5
Original file line numberDiff line numberDiff line change
@@ -202,11 +202,7 @@ impl TyExt for Ty {
202202
fn callable_sig(&self, db: &dyn HirDatabase) -> Option<CallableSig> {
203203
match self.kind(Interner) {
204204
TyKind::Function(fn_ptr) => Some(CallableSig::from_fn_ptr(fn_ptr)),
205-
TyKind::FnDef(def, parameters) => {
206-
let callable_def = db.lookup_intern_callable_def((*def).into());
207-
let sig = db.callable_item_signature(callable_def);
208-
Some(sig.substitute(Interner, parameters))
209-
}
205+
TyKind::FnDef(def, parameters) => Some(CallableSig::from_def(db, *def, parameters)),
210206
TyKind::Closure(.., substs) => ClosureSubst(substs).sig_ty().callable_sig(db),
211207
_ => None,
212208
}

crates/hir-ty/src/display.rs

+32-7
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use std::{
88
};
99

1010
use base_db::CrateId;
11-
use chalk_ir::{BoundVar, TyKind};
11+
use chalk_ir::{BoundVar, Safety, TyKind};
1212
use hir_def::{
1313
data::adt::VariantData,
1414
db::DefDatabase,
@@ -41,7 +41,7 @@ use crate::{
4141
primitive, to_assoc_type_id,
4242
utils::{self, detect_variant_from_bytes, generics, ClosureSubst},
4343
AdtId, AliasEq, AliasTy, Binders, CallableDefId, CallableSig, Const, ConstScalar, ConstValue,
44-
DomainGoal, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives,
44+
DomainGoal, FnAbi, GenericArg, ImplTraitId, Interner, Lifetime, LifetimeData, LifetimeOutlives,
4545
MemoryMap, Mutability, OpaqueTy, ProjectionTy, ProjectionTyExt, QuantifiedWhereClause, Scalar,
4646
Substitution, TraitEnvironment, TraitRef, TraitRefExt, Ty, TyExt, WhereClause,
4747
};
@@ -879,16 +879,27 @@ impl HirDisplay for Ty {
879879
// function pointer type.
880880
return sig.hir_fmt(f);
881881
}
882+
if let Safety::Unsafe = sig.safety {
883+
write!(f, "unsafe ")?;
884+
}
885+
if !matches!(sig.abi, FnAbi::Rust) {
886+
f.write_str("extern \"")?;
887+
f.write_str(sig.abi.as_str())?;
888+
f.write_str("\" ")?;
889+
}
882890

883-
f.start_location_link(def.into());
884891
match def {
885892
CallableDefId::FunctionId(ff) => {
886-
write!(f, "fn {}", db.function_data(ff).name.display(f.db.upcast()))?
893+
write!(f, "fn ")?;
894+
f.start_location_link(def.into());
895+
write!(f, "{}", db.function_data(ff).name.display(f.db.upcast()))?
887896
}
888897
CallableDefId::StructId(s) => {
898+
f.start_location_link(def.into());
889899
write!(f, "{}", db.struct_data(s).name.display(f.db.upcast()))?
890900
}
891901
CallableDefId::EnumVariantId(e) => {
902+
f.start_location_link(def.into());
892903
write!(f, "{}", db.enum_variant_data(e).name.display(f.db.upcast()))?
893904
}
894905
};
@@ -1316,9 +1327,19 @@ fn hir_fmt_generics(
13161327

13171328
impl HirDisplay for CallableSig {
13181329
fn hir_fmt(&self, f: &mut HirFormatter<'_>) -> Result<(), HirDisplayError> {
1330+
let CallableSig { params_and_return: _, is_varargs, safety, abi: _ } = *self;
1331+
if let Safety::Unsafe = safety {
1332+
write!(f, "unsafe ")?;
1333+
}
1334+
// FIXME: Enable this when the FIXME on FnAbi regarding PartialEq is fixed.
1335+
// if !matches!(abi, FnAbi::Rust) {
1336+
// f.write_str("extern \"")?;
1337+
// f.write_str(abi.as_str())?;
1338+
// f.write_str("\" ")?;
1339+
// }
13191340
write!(f, "fn(")?;
13201341
f.write_joined(self.params(), ", ")?;
1321-
if self.is_varargs {
1342+
if is_varargs {
13221343
if self.params().is_empty() {
13231344
write!(f, "...")?;
13241345
} else {
@@ -1683,11 +1704,15 @@ impl HirDisplay for TypeRef {
16831704
inner.hir_fmt(f)?;
16841705
write!(f, "]")?;
16851706
}
1686-
&TypeRef::Fn(ref parameters, is_varargs, is_unsafe) => {
1687-
// FIXME: Function pointer qualifiers.
1707+
&TypeRef::Fn(ref parameters, is_varargs, is_unsafe, ref abi) => {
16881708
if is_unsafe {
16891709
write!(f, "unsafe ")?;
16901710
}
1711+
if let Some(abi) = abi {
1712+
f.write_str("extern \"")?;
1713+
f.write_str(abi)?;
1714+
f.write_str("\" ")?;
1715+
}
16911716
write!(f, "fn(")?;
16921717
if let Some(((_, return_type), function_parameters)) = parameters.split_last() {
16931718
for index in 0..function_parameters.len() {

crates/hir-ty/src/infer.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -1453,10 +1453,10 @@ impl Expectation {
14531453
match self {
14541454
Expectation::HasType(ety) => {
14551455
let ety = table.resolve_ty_shallow(ety);
1456-
if !ety.is_ty_var() {
1457-
Expectation::HasType(ety)
1458-
} else {
1456+
if ety.is_ty_var() {
14591457
Expectation::None
1458+
} else {
1459+
Expectation::HasType(ety)
14601460
}
14611461
}
14621462
Expectation::RValueLikeUnsized(ety) => Expectation::RValueLikeUnsized(ety.clone()),

crates/hir-ty/src/infer/closure.rs

+7-3
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,8 @@ use crate::{
2727
static_lifetime, to_chalk_trait_id,
2828
traits::FnTrait,
2929
utils::{self, generics, Generics},
30-
Adjust, Adjustment, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy, FnPointer, FnSig,
31-
Interner, Substitution, Ty, TyExt,
30+
Adjust, Adjustment, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy, FnAbi, FnPointer,
31+
FnSig, Interner, Substitution, Ty, TyExt,
3232
};
3333

3434
use super::{Expectation, InferenceContext};
@@ -98,7 +98,11 @@ impl InferenceContext<'_> {
9898
cov_mark::hit!(dyn_fn_param_informs_call_site_closure_signature);
9999
return Some(FnPointer {
100100
num_binders: bound.len(Interner),
101-
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
101+
sig: FnSig {
102+
abi: FnAbi::RustCall,
103+
safety: chalk_ir::Safety::Safe,
104+
variadic: false,
105+
},
102106
substitution: FnSubst(Substitution::from_iter(Interner, sig_tys)),
103107
});
104108
}

crates/hir-ty/src/infer/coerce.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ use crate::{
2424
},
2525
static_lifetime,
2626
utils::ClosureSubst,
27-
Canonical, DomainGoal, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution,
27+
Canonical, DomainGoal, FnAbi, FnPointer, FnSig, Guidance, InEnvironment, Interner, Solution,
2828
Substitution, TraitEnvironment, Ty, TyBuilder, TyExt,
2929
};
3030

@@ -691,7 +691,7 @@ fn coerce_closure_fn_ty(closure_substs: &Substitution, safety: chalk_ir::Safety)
691691
match closure_sig.kind(Interner) {
692692
TyKind::Function(fn_ty) => TyKind::Function(FnPointer {
693693
num_binders: fn_ty.num_binders,
694-
sig: FnSig { safety, ..fn_ty.sig },
694+
sig: FnSig { safety, abi: FnAbi::Rust, variadic: fn_ty.sig.variadic },
695695
substitution: fn_ty.substitution.clone(),
696696
})
697697
.intern(Interner),

crates/hir-ty/src/infer/expr.rs

+8-4
Original file line numberDiff line numberDiff line change
@@ -39,9 +39,9 @@ use crate::{
3939
static_lifetime, to_chalk_trait_id,
4040
traits::FnTrait,
4141
utils::{generics, Generics},
42-
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, FnPointer, FnSig, FnSubst,
43-
Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder, TyExt,
44-
TyKind,
42+
Adjust, Adjustment, AdtId, AutoBorrow, Binders, CallableDefId, FnAbi, FnPointer, FnSig,
43+
FnSubst, Interner, Rawness, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyBuilder,
44+
TyExt, TyKind,
4545
};
4646

4747
use super::{
@@ -224,7 +224,11 @@ impl InferenceContext<'_> {
224224

225225
let sig_ty = TyKind::Function(FnPointer {
226226
num_binders: 0,
227-
sig: FnSig { abi: (), safety: chalk_ir::Safety::Safe, variadic: false },
227+
sig: FnSig {
228+
abi: FnAbi::RustCall,
229+
safety: chalk_ir::Safety::Safe,
230+
variadic: false,
231+
},
228232
substitution: FnSubst(
229233
Substitution::from_iter(Interner, sig_tys.iter().cloned())
230234
.shifted_in(Interner),

crates/hir-ty/src/interner.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@
33
44
use crate::{
55
chalk_db, tls, AliasTy, CanonicalVarKind, CanonicalVarKinds, ClosureId, Const, ConstData,
6-
ConstScalar, Constraint, Constraints, FnDefId, GenericArg, GenericArgData, Goal, GoalData,
7-
Goals, InEnvironment, Lifetime, LifetimeData, OpaqueTy, OpaqueTyId, ProgramClause,
6+
ConstScalar, Constraint, Constraints, FnAbi, FnDefId, GenericArg, GenericArgData, Goal,
7+
GoalData, Goals, InEnvironment, Lifetime, LifetimeData, OpaqueTy, OpaqueTyId, ProgramClause,
88
ProgramClauseData, ProgramClauses, ProjectionTy, QuantifiedWhereClause, QuantifiedWhereClauses,
99
Substitution, Ty, TyData, TyKind, VariableKind, VariableKinds,
1010
};
@@ -71,7 +71,7 @@ impl chalk_ir::interner::Interner for Interner {
7171
type DefId = InternId;
7272
type InternedAdtId = hir_def::AdtId;
7373
type Identifier = TypeAliasId;
74-
type FnAbi = ();
74+
type FnAbi = FnAbi;
7575

7676
fn debug_adt_id(
7777
type_kind_id: chalk_db::AdtId,

0 commit comments

Comments
 (0)