Skip to content

Commit

Permalink
Use typeck_results.node_type to resolve types (#351)
Browse files Browse the repository at this point in the history
...in the suspicious trait object lint so that all type paths are handled,
even in the case of a possible associated type.
  • Loading branch information
thomcc authored Jul 6, 2023
1 parent 07bec8d commit 71df64e
Show file tree
Hide file tree
Showing 4 changed files with 66 additions and 23 deletions.
23 changes: 23 additions & 0 deletions plrust/src/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::<i32>("SELECT rust_rand()").unwrap();
assert!(rand.is_some());
}

#[pg_test]
#[search_path(@extschema@)]
fn plrust_returns_setof() -> spi::Result<()> {
Expand Down Expand Up @@ -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(),
)
Expand Down
26 changes: 3 additions & 23 deletions plrustc/plrustc/src/lints/sus_trait_object.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
use hir::def::{DefKind, Res};
use rustc_hir as hir;
use rustc_lint::{LateContext, LateLintPass, LintContext};
use rustc_middle::ty;
Expand Down Expand Up @@ -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,
Expand Down
30 changes: 30 additions & 0 deletions plrustc/plrustc/uitests/sus_trait_object_gat.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#![crate_type = "lib"]

trait Object {
type Output;
}

impl<T: ?Sized> Object for T {
type Output = &'static u64;
}

trait HasGenericAssoc {
type Ohno<'a>: ?Sized;
}

impl HasGenericAssoc for () {
type Ohno<'a> = dyn Object<Output = &'a u64>;
}

fn foo<'a, T: ?Sized>(x: <T as Object>::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)
}
10 changes: 10 additions & 0 deletions plrustc/plrustc/uitests/sus_trait_object_gat.stderr
Original file line number Diff line number Diff line change
@@ -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

0 comments on commit 71df64e

Please sign in to comment.