Skip to content

Commit 8568121

Browse files
Need to use hybrid param-env to make sure implication is not circular
1 parent b5a904a commit 8568121

File tree

3 files changed

+55
-2
lines changed

3 files changed

+55
-2
lines changed

compiler/rustc_hir_analysis/src/check/compare_impl_item.rs

+13-2
Original file line numberDiff line numberDiff line change
@@ -662,8 +662,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
662662
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
663663
let impl_trait_ref =
664664
tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity();
665-
let param_env = tcx.param_env(impl_m_def_id);
666-
667665
// First, check a few of the same things as `compare_impl_method`,
668666
// just so we don't ICE during substitution later.
669667
check_method_is_structurally_compatible(tcx, impl_m, trait_m, impl_trait_ref, true)?;
@@ -689,6 +687,19 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
689687
let trait_to_placeholder_args =
690688
impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
691689

690+
let hybrid_preds = tcx
691+
.predicates_of(impl_m.container_id(tcx))
692+
.instantiate_identity(tcx)
693+
.into_iter()
694+
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_placeholder_args))
695+
.map(|(clause, _)| clause);
696+
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
697+
let param_env = traits::normalize_param_env_or_error(
698+
tcx,
699+
param_env,
700+
ObligationCause::misc(tcx.def_span(impl_m_def_id), impl_m_def_id),
701+
);
702+
692703
let infcx = &tcx.infer_ctxt().build();
693704
let ocx = ObligationCtxt::new(infcx);
694705

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
#![feature(return_position_impl_trait_in_trait)]
2+
3+
trait Extend {
4+
fn extend<'a: 'a>(_: &'a str) -> (impl Sized + 'a, &'static str);
5+
}
6+
7+
impl Extend for () {
8+
fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
9+
//~^ ERROR in type `&'static &'a ()`, reference has a longer lifetime than the data it references
10+
where
11+
'a: 'static,
12+
{
13+
(None, s)
14+
}
15+
}
16+
17+
// This indirection is not necessary for reproduction,
18+
// but it makes this test future-proof against #114936.
19+
fn extend<T: Extend>(s: &str) -> &'static str {
20+
<T as Extend>::extend(s).1
21+
}
22+
23+
fn main() {
24+
let use_after_free = extend::<()>(&String::from("temporary"));
25+
println!("{}", use_after_free);
26+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references
2+
--> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:38
3+
|
4+
LL | fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: the pointer is valid for the static lifetime
8+
note: but the referenced data is only valid for the lifetime `'a` as defined here
9+
--> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:15
10+
|
11+
LL | fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
12+
| ^^
13+
14+
error: aborting due to previous error
15+
16+
For more information about this error, try `rustc --explain E0491`.

0 commit comments

Comments
 (0)