diff --git a/crates/flux-desugar/src/resolver.rs b/crates/flux-desugar/src/resolver.rs index 73fafc4ae2..2b2343d490 100644 --- a/crates/flux-desugar/src/resolver.rs +++ b/crates/flux-desugar/src/resolver.rs @@ -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() { @@ -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()); diff --git a/crates/flux-fhir-analysis/locales/en-US.ftl b/crates/flux-fhir-analysis/locales/en-US.ftl index df28dac7fa..2a241d41aa 100644 --- a/crates/flux-fhir-analysis/locales/en-US.ftl +++ b/crates/flux-fhir-analysis/locales/en-US.ftl @@ -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_}` diff --git a/crates/flux-fhir-analysis/src/conv/mod.rs b/crates/flux-fhir-analysis/src/conv/mod.rs index 0acbe545bd..5055d7fcd9 100644 --- a/crates/flux-fhir-analysis/src/conv/mod.rs +++ b/crates/flux-fhir-analysis/src/conv/mod.rs @@ -1689,7 +1689,7 @@ impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt
{ } } 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)?, @@ -1938,6 +1938,14 @@ impl<'genv, 'tcx: 'genv, P: ConvPhase<'genv, 'tcx>> ConvCtxt
{
}
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 {
@@ -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 {
diff --git a/tests/tests/neg/error_messages/conv/mismatched_generics.rs b/tests/tests/neg/error_messages/conv/mismatched_generics.rs
index b24638f165..9f5f1f3c76 100644
--- a/tests/tests/neg/error_messages/conv/mismatched_generics.rs
+++ b/tests/tests/neg/error_messages/conv/mismatched_generics.rs
@@ -1,4 +1,6 @@
-use flux_rs::*;
+#![feature(extern_types)]
+
+use flux_rs::attrs::*;
#[refined_by(n: int)]
struct S {
@@ -52,3 +54,10 @@ flux_rs::defs! {
#[flux_rs::opaque]
#[flux_rs::refined_by(f: MyOpaqueSort