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)] //~ Error user defined opaque sorts have no generics but found 1 struct Y {} + +unsafe extern "C" { + type A; +} + +#[sig(fn(x: &A))] //~ ERROR generic arguments are not allowed on foreign types +fn test00(x: &A) {}