Skip to content

Commit

Permalink
Check that unnormalized sig is WF, add test
Browse files Browse the repository at this point in the history
  • Loading branch information
compiler-errors committed Dec 11, 2022
1 parent d535e47 commit 45d1e92
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 21 deletions.
34 changes: 13 additions & 21 deletions compiler/rustc_hir_analysis/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -256,10 +256,21 @@ fn compare_predicate_entailment<'tcx>(
infer::HigherRankedType,
tcx.fn_sig(impl_m.def_id),
);
let unnormalized_impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(unnormalized_impl_sig));

// We need to check that the impl's args are well-formed given
// the hybrid param-env (impl + trait method where-clauses).
ocx.register_obligation(traits::Obligation::new(
tcx,
cause.clone(),
param_env,
ty::Binder::dummy(ty::PredicateKind::WellFormed(
tcx.mk_fn_ptr(ty::Binder::dummy(unnormalized_impl_sig)).into(),
)),
));

let norm_cause = ObligationCause::misc(impl_m_span, impl_m_hir_id);
let impl_sig = ocx.normalize(&norm_cause, param_env, unnormalized_impl_sig);
let impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(impl_sig));
let impl_fty = ocx.normalize(&norm_cause, param_env, unnormalized_impl_fty);
debug!("compare_impl_method: impl_fty={:?}", impl_fty);

let trait_sig = tcx.bound_fn_sig(trait_m.def_id).subst(tcx, trait_to_placeholder_substs);
Expand Down Expand Up @@ -300,25 +311,6 @@ fn compare_predicate_entailment<'tcx>(
return Err(emitted);
}

// Finally, we need to check that the impl's args are well-formed given
// the hybrid param-env (impl + trait method where-clauses).
for (unnormalized_arg, arg) in
std::iter::zip(unnormalized_impl_sig.inputs_and_output, impl_sig.inputs_and_output)
{
ocx.register_obligation(traits::Obligation::new(
tcx,
cause.clone(),
param_env,
ty::Binder::dummy(ty::PredicateKind::WellFormed(unnormalized_arg.into())),
));
ocx.register_obligation(traits::Obligation::new(
tcx,
cause.clone(),
param_env,
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg.into())),
));
}

// Check that all obligations are satisfied by the implementation's
// version.
let errors = ocx.select_all_or_error();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
trait Project {
type Ty;
}
impl Project for &'_ &'_ () {
type Ty = ();
}
trait Trait {
fn get<'s>(s: &'s str, _: ()) -> &'static str;
}
impl Trait for () {
fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
//~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
s
}
}
fn main() {
let val = <() as Trait>::get(&String::from("blah blah blah"), ());
println!("{}", val);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
--> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
|
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'s` as defined here...
--> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:12
|
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
| ^^
note: ...so that the method type is compatible with trait
--> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
|
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
= note: expected `fn(&'s str, ()) -> &'static str`
found `fn(&str, ()) -> &'static str`
= note: but, the lifetime must be valid for the static lifetime...
note: ...so that the reference type `&'static &()` does not outlive the data it points at
--> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
|
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to previous error

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

0 comments on commit 45d1e92

Please sign in to comment.