Skip to content

Commit

Permalink
Check RPIT and AFIT hidden types are well-formed considering regions
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors authored and aliemjay committed Aug 19, 2023
1 parent aec4a4f commit ca0634b
Show file tree
Hide file tree
Showing 4 changed files with 43 additions and 17 deletions.
10 changes: 5 additions & 5 deletions compiler/rustc_hir_analysis/src/check/check.rs
Original file line number Diff line number Diff line change
Expand Up @@ -460,8 +460,6 @@ fn check_opaque_meets_bounds<'tcx>(
return Err(guar);
}
match origin {
// Checked when type checking the function containing them.
hir::OpaqueTyOrigin::FnReturn(..) | hir::OpaqueTyOrigin::AsyncFn(..) => {}
// Nested opaque types occur only in associated types:
// ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
// They can only be referenced as `<Opaque<T> as Trait<&'static T>>::AssocTy`.
Expand All @@ -470,9 +468,11 @@ fn check_opaque_meets_bounds<'tcx>(
hir::OpaqueTyOrigin::TyAlias { .. }
if tcx.def_kind(tcx.parent(def_id.to_def_id())) == DefKind::OpaqueTy => {}
// Can have different predicates to their defining use
hir::OpaqueTyOrigin::TyAlias { .. } => {
let wf_tys = ocx.assumed_wf_types_and_report_errors(param_env, def_id)?;
let implied_bounds = infcx.implied_bounds_tys(param_env, def_id, wf_tys);
hir::OpaqueTyOrigin::TyAlias { .. }
| hir::OpaqueTyOrigin::FnReturn(..)
| hir::OpaqueTyOrigin::AsyncFn(..) => {
let wf_tys = ocx.assumed_wf_types_and_report_errors(param_env, defining_use_anchor)?;
let implied_bounds = infcx.implied_bounds_tys(param_env, defining_use_anchor, wf_tys);
let outlives_env = OutlivesEnvironment::with_bounds(param_env, implied_bounds);
ocx.resolve_regions_and_report_errors(defining_use_anchor, &outlives_env)?;
}
Expand Down
13 changes: 1 addition & 12 deletions compiler/rustc_ty_utils/src/implied_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -118,18 +118,7 @@ fn assumed_wf_types<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> &'tcx [(Ty<'
}
},
DefKind::AssocConst | DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
DefKind::OpaqueTy => match tcx.def_kind(tcx.local_parent(def_id)) {
DefKind::TyAlias { .. } => ty::List::empty(),
DefKind::AssocTy => tcx.assumed_wf_types(tcx.local_parent(def_id)),
// Nested opaque types only occur in associated types:
// ` type Opaque<T> = impl Trait<&'static T, AssocTy = impl Nested>; `
// assumed_wf_types should include those of `Opaque<T>`, `Opaque<T>` itself
// and `&'static T`.
DefKind::OpaqueTy => bug!("unimplemented implied bounds for nested opaque types"),
def_kind => {
bug!("unimplemented implied bounds for opaque types with parent {def_kind:?}")
}
},
DefKind::OpaqueTy => bug!("implied bounds are not defined for opaques"),
DefKind::Mod
| DefKind::Struct
| DefKind::Union
Expand Down
21 changes: 21 additions & 0 deletions tests/ui/impl-trait/check-rpit-is-wf-regions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
type Static<'a> = &'static &'a ();

trait Extend<'a> {
fn extend(self, _: &'a str) -> &'static str;
}

impl<'a> Extend<'a> for Static<'a> {
fn extend(self, s: &'a str) -> &'static str {
s
}
}

fn boom<'a>(arg: Static<'_>) -> impl Extend<'a> {
//~^ ERROR in type `&'static &'a ()`, reference has a longer lifetime than the data it references
arg
}

fn main() {
let y = boom(&&()).extend(&String::from("temporary"));
println!("{}", y);
}
16 changes: 16 additions & 0 deletions tests/ui/impl-trait/check-rpit-is-wf-regions.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references
--> $DIR/check-rpit-is-wf-regions.rs:13:33
|
LL | fn boom<'a>(arg: Static<'_>) -> impl Extend<'a> {
| ^^^^^^^^^^^^^^^
|
= note: the pointer is valid for the static lifetime
note: but the referenced data is only valid for the lifetime `'a` as defined here
--> $DIR/check-rpit-is-wf-regions.rs:13:9
|
LL | fn boom<'a>(arg: Static<'_>) -> impl Extend<'a> {
| ^^

error: aborting due to previous error

For more information about this error, try `rustc --explain E0491`.

0 comments on commit ca0634b

Please sign in to comment.