diff --git a/plrust/src/tests.rs b/plrust/src/tests.rs index 4a5e421c..cbbadbca 100644 --- a/plrust/src/tests.rs +++ b/plrust/src/tests.rs @@ -294,6 +294,28 @@ mod tests { assert!(res.is_err()); } + // Regression for #348 + #[pg_test] + #[cfg(not(feature = "sandboxed"))] + #[search_path(@extschema@)] + fn plrust_rand_dep() { + let definition = r#" + CREATE FUNCTION rust_rand() RETURNS INT + IMMUTABLE STRICT + LANGUAGE PLRUST AS + $$ + [dependencies] + rand = "0.8.5" + [code] + Ok(Some(rand::random())) + $$; + "#; + Spi::run(definition).unwrap(); + + let rand = Spi::get_one::("SELECT rust_rand()").unwrap(); + assert!(rand.is_some()); + } + #[pg_test] #[search_path(@extschema@)] fn plrust_returns_setof() -> spi::Result<()> { @@ -1405,6 +1427,7 @@ pub mod pg_test { owo-colors = "=3.5.0" tokio = { version = "=1.19.2", features = ["rt", "net"]} plutonium = "*" +rand = "*" "# .as_bytes(), ) diff --git a/plrustc/plrustc/src/lints/sus_trait_object.rs b/plrustc/plrustc/src/lints/sus_trait_object.rs index 1768ec3e..3d72959a 100644 --- a/plrustc/plrustc/src/lints/sus_trait_object.rs +++ b/plrustc/plrustc/src/lints/sus_trait_object.rs @@ -1,4 +1,3 @@ -use hir::def::{DefKind, Res}; use rustc_hir as hir; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::ty; @@ -29,28 +28,9 @@ impl<'tcx> LateLintPass<'tcx> for PlrustSuspiciousTraitObject { let hir::GenericArg::Type(ty) = arg else { continue; }; - let is_trait_obj = match &ty.kind { - hir::TyKind::TraitObject(..) => true, - hir::TyKind::Path(qpath) => { - let res = cx.qpath_res(qpath, ty.hir_id); - let did = match res { - Res::Def(DefKind::TyAlias | DefKind::AssocTy, def_id) => def_id, - Res::SelfTyAlias { alias_to, .. } => alias_to, - _ => continue, - }; - let binder = cx.tcx.type_of(did); - let ty = binder.subst_identity(); - if matches!(ty.kind(), ty::TyKind::Dynamic(..)) { - true - } else { - match cx.tcx.try_normalize_erasing_regions(cx.param_env, ty) { - Ok(t) => matches!(t.kind(), ty::TyKind::Dynamic(..)), - _ => false, - } - } - } - _ => false, - }; + let typeck_results = cx.typeck_results(); + let is_trait_obj = + matches!(typeck_results.node_type(ty.hir_id).kind(), ty::Dynamic(..)); if is_trait_obj { cx.lint( PLRUST_SUSPICIOUS_TRAIT_OBJECT, diff --git a/plrustc/plrustc/uitests/sus_trait_object_gat.rs b/plrustc/plrustc/uitests/sus_trait_object_gat.rs new file mode 100644 index 00000000..c1be16f4 --- /dev/null +++ b/plrustc/plrustc/uitests/sus_trait_object_gat.rs @@ -0,0 +1,30 @@ +#![crate_type = "lib"] + +trait Object { + type Output; +} + +impl Object for T { + type Output = &'static u64; +} + +trait HasGenericAssoc { + type Ohno<'a>: ?Sized; +} + +impl HasGenericAssoc for () { + type Ohno<'a> = dyn Object; +} + +fn foo<'a, T: ?Sized>(x: ::Output) -> &'a u64 { + x +} + +fn transmute_lifetime<'a, 'b>(x: &'a u64) -> &'b u64 { + foo::<<() as HasGenericAssoc>::Ohno<'a>>(x) +} + +pub fn get_dangling<'a>() -> &'a u64 { + let x = 0; + transmute_lifetime(&x) +} diff --git a/plrustc/plrustc/uitests/sus_trait_object_gat.stderr b/plrustc/plrustc/uitests/sus_trait_object_gat.stderr new file mode 100644 index 00000000..e94571b6 --- /dev/null +++ b/plrustc/plrustc/uitests/sus_trait_object_gat.stderr @@ -0,0 +1,10 @@ +error: using trait objects in turbofish position is forbidden by PL/Rust + --> $DIR/sus_trait_object_gat.rs:24:5 + | +LL | foo::<<() as HasGenericAssoc>::Ohno<'a>>(x) + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: `-F plrust-suspicious-trait-object` implied by `-F plrust-lints` + +error: aborting due to previous error +