Skip to content

Commit 6a56c65

Browse files
authored
Fully resolve aliases in plrust-suspicious-trait-object (#335)
1 parent eee4133 commit 6a56c65

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

plrustc/plrustc/src/lints/sus_trait_object.rs

Lines changed: 25 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
1+
use hir::def::{DefKind, Res};
12
use rustc_hir as hir;
23
use rustc_lint::{LateContext, LateLintPass, LintContext};
4+
use rustc_middle::ty;
35

46
declare_plrust_lint!(
57
pub(crate) PLRUST_SUSPICIOUS_TRAIT_OBJECT,
@@ -27,7 +29,29 @@ impl<'tcx> LateLintPass<'tcx> for PlrustSuspiciousTraitObject {
2729
let hir::GenericArg::Type(ty) = arg else {
2830
continue;
2931
};
30-
if let hir::TyKind::TraitObject(..) = &ty.kind {
32+
let is_trait_obj = match &ty.kind {
33+
hir::TyKind::TraitObject(..) => true,
34+
hir::TyKind::Path(qpath) => {
35+
let res = cx.qpath_res(qpath, ty.hir_id);
36+
let did = match res {
37+
Res::Def(DefKind::TyAlias | DefKind::AssocTy, def_id) => def_id,
38+
Res::SelfTyAlias { alias_to, .. } => alias_to,
39+
_ => continue,
40+
};
41+
let binder = cx.tcx.type_of(did);
42+
let ty = binder.subst_identity();
43+
if matches!(ty.kind(), ty::TyKind::Dynamic(..)) {
44+
true
45+
} else {
46+
match cx.tcx.try_normalize_erasing_regions(cx.param_env, ty) {
47+
Ok(t) => matches!(t.kind(), ty::TyKind::Dynamic(..)),
48+
_ => false,
49+
}
50+
}
51+
}
52+
_ => false,
53+
};
54+
if is_trait_obj {
3155
cx.lint(
3256
PLRUST_SUSPICIOUS_TRAIT_OBJECT,
3357
"using trait objects in turbofish position is forbidden by PL/Rust",
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#![crate_type = "lib"]
2+
trait Object {
3+
type Output;
4+
}
5+
6+
impl<T: ?Sized> Object for T {
7+
type Output = &'static u64;
8+
}
9+
10+
fn foo<'a, T: ?Sized>(x: <T as Object>::Output) -> &'a u64 {
11+
x
12+
}
13+
14+
fn transmute_lifetime<'a, 'b>(x: &'a u64) -> &'b u64 {
15+
type A<'x> = dyn Object<Output = &'x u64>;
16+
type B<'x> = A<'x>;
17+
foo::<B<'a>>(x)
18+
}
19+
20+
// And yes this is a genuine `transmute_lifetime`!
21+
fn get_dangling<'a>() -> &'a u64 {
22+
let x = 0;
23+
transmute_lifetime(&x)
24+
}
25+
26+
pub fn problems() -> &'static u64 {
27+
get_dangling()
28+
}
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: using trait objects in turbofish position is forbidden by PL/Rust
2+
--> $DIR/sus_trait_obj_alias.rs:17:5
3+
|
4+
LL | foo::<B<'a>>(x)
5+
| ^^^^^^^^^^^^
6+
|
7+
= note: `-F plrust-suspicious-trait-object` implied by `-F plrust-lints`
8+
9+
error: aborting due to previous error
10+

0 commit comments

Comments
 (0)