Need to use hybrid param-env to make sure implication is not circular
This commit is contained in:
parent
b5a904a9d4
commit
8568121996
@ -662,8 +662,6 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
|
||||
let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
|
||||
let impl_trait_ref =
|
||||
tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap().instantiate_identity();
|
||||
let param_env = tcx.param_env(impl_m_def_id);
|
||||
|
||||
// First, check a few of the same things as `compare_impl_method`,
|
||||
// just so we don't ICE during substitution later.
|
||||
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>(
|
||||
let trait_to_placeholder_args =
|
||||
impl_to_placeholder_args.rebase_onto(tcx, impl_m.container_id(tcx), trait_to_impl_args);
|
||||
|
||||
let hybrid_preds = tcx
|
||||
.predicates_of(impl_m.container_id(tcx))
|
||||
.instantiate_identity(tcx)
|
||||
.into_iter()
|
||||
.chain(tcx.predicates_of(trait_m.def_id).instantiate_own(tcx, trait_to_placeholder_args))
|
||||
.map(|(clause, _)| clause);
|
||||
let param_env = ty::ParamEnv::new(tcx.mk_clauses_from_iter(hybrid_preds), Reveal::UserFacing);
|
||||
let param_env = traits::normalize_param_env_or_error(
|
||||
tcx,
|
||||
param_env,
|
||||
ObligationCause::misc(tcx.def_span(impl_m_def_id), impl_m_def_id),
|
||||
);
|
||||
|
||||
let infcx = &tcx.infer_ctxt().build();
|
||||
let ocx = ObligationCtxt::new(infcx);
|
||||
|
||||
|
@ -0,0 +1,26 @@
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
|
||||
trait Extend {
|
||||
fn extend<'a: 'a>(_: &'a str) -> (impl Sized + 'a, &'static str);
|
||||
}
|
||||
|
||||
impl Extend for () {
|
||||
fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
|
||||
//~^ ERROR in type `&'static &'a ()`, reference has a longer lifetime than the data it references
|
||||
where
|
||||
'a: 'static,
|
||||
{
|
||||
(None, s)
|
||||
}
|
||||
}
|
||||
|
||||
// This indirection is not necessary for reproduction,
|
||||
// but it makes this test future-proof against #114936.
|
||||
fn extend<T: Extend>(s: &str) -> &'static str {
|
||||
<T as Extend>::extend(s).1
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let use_after_free = extend::<()>(&String::from("temporary"));
|
||||
println!("{}", use_after_free);
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
error[E0491]: in type `&'static &'a ()`, reference has a longer lifetime than the data it references
|
||||
--> $DIR/rpitit-hidden-types-self-implied-wf-via-param.rs:8:38
|
||||
|
|
||||
LL | fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= 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/rpitit-hidden-types-self-implied-wf-via-param.rs:8:15
|
||||
|
|
||||
LL | fn extend<'a: 'a>(s: &'a str) -> (Option<&'static &'a ()>, &'static str)
|
||||
| ^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0491`.
|
Loading…
x
Reference in New Issue
Block a user