Skip to content

Commit

Permalink
Resolve foreign types (#1005)
Browse files Browse the repository at this point in the history
  • Loading branch information
nilehmann authored Feb 27, 2025
1 parent 439403d commit 08dae15
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 2 deletions.
20 changes: 20 additions & 0 deletions crates/flux-desugar/src/resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -157,6 +157,10 @@ impl<'genv, 'tcx> CrateResolver<'genv, 'tcx> {
ItemKind::Trait(..) => DefKind::Trait,
ItemKind::Mod(..) => DefKind::Mod,
ItemKind::Const(..) => DefKind::Const,
ItemKind::ForeignMod { items, .. } => {
self.define_foreign_items(items);
continue;
}
_ => continue,
};
if let Some(ns) = def_kind.ns() {
Expand All @@ -169,6 +173,22 @@ impl<'genv, 'tcx> CrateResolver<'genv, 'tcx> {
}
}

fn define_foreign_items(&mut self, items: &[rustc_hir::ForeignItemRef]) {
for item_ref in items {
let item = self.genv.hir().foreign_item(item_ref.id);
match item.kind {
rustc_hir::ForeignItemKind::Type => {
self.define_res_in(
item.ident.name,
fhir::Res::Def(DefKind::ForeignTy, item.owner_id.to_def_id()),
TypeNS,
);
}
rustc_hir::ForeignItemKind::Fn(..) | rustc_hir::ForeignItemKind::Static(..) => {}
}
}
}

fn define_enum_variants(&mut self, enum_def: &rustc_hir::EnumDef) {
let Some(v0) = enum_def.variants.first() else { return };
let enum_def_id = self.genv.tcx().parent(v0.def_id.to_def_id());
Expand Down
3 changes: 3 additions & 0 deletions crates/flux-fhir-analysis/locales/en-US.ftl
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,9 @@ fhir_analysis_generics_on_ty_param =
fhir_analysis_generics_on_self_ty =
generic arguments are not allowed on self type
fhir_analysis_generics_on_foreign_ty =
generic arguments are not allowed on foreign types
fhir_analysis_invalid_assoc_reft =
associated refinement `{$name}` is not a member of trait `{$trait_}`
Expand Down
17 changes: 16 additions & 1 deletion crates/flux-fhir-analysis/src/conv/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1689,7 +1689,7 @@ impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt<P> {
}
}
fhir::Res::Def(DefKind::ForeignTy, def_id) => {
self.check_self_ty_generics(path)?;
self.check_foreign_ty_generics(path)?;
rty::BaseTy::Foreign(def_id)
}
fhir::Res::Def(kind, def_id) => self.report_expected_type(path.span, kind, def_id)?,
Expand Down Expand Up @@ -1938,6 +1938,14 @@ impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt<P> {
}
Ok(())
}

fn check_foreign_ty_generics(&mut self, path: &fhir::Path<'_>) -> QueryResult {
if !path.last_segment().args.is_empty() {
let err = errors::GenericsOnForeignTy { span: path.span };
Err(self.emit(err))?;
}
Ok(())
}
}

fn prim_ty_to_bty(prim_ty: rustc_hir::PrimTy) -> rty::BaseTy {
Expand Down Expand Up @@ -2694,6 +2702,13 @@ mod errors {
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(fhir_analysis_generics_on_foreign_ty, code = E0999)]
pub(super) struct GenericsOnForeignTy {
#[primary_span]
pub span: Span,
}

#[derive(Diagnostic)]
#[diag(fhir_analysis_invalid_assoc_reft, code = E0999)]
pub struct InvalidAssocReft {
Expand Down
11 changes: 10 additions & 1 deletion tests/tests/neg/error_messages/conv/mismatched_generics.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
use flux_rs::*;
#![feature(extern_types)]

use flux_rs::attrs::*;

#[refined_by(n: int)]
struct S {
Expand Down Expand Up @@ -52,3 +54,10 @@ flux_rs::defs! {
#[flux_rs::opaque]
#[flux_rs::refined_by(f: MyOpaqueSort<int>)] //~ Error user defined opaque sorts have no generics but found 1
struct Y {}

unsafe extern "C" {
type A;
}

#[sig(fn(x: &A<i32>))] //~ ERROR generic arguments are not allowed on foreign types
fn test00(x: &A) {}

0 comments on commit 08dae15

Please sign in to comment.