Skip to content

Commit 45d1e92

Browse files
Check that unnormalized sig is WF, add test
1 parent d535e47 commit 45d1e92

File tree

3 files changed

+60
-21
lines changed

3 files changed

+60
-21
lines changed

compiler/rustc_hir_analysis/src/check/compare_method.rs

+13-21
Original file line numberDiff line numberDiff line change
@@ -256,10 +256,21 @@ fn compare_predicate_entailment<'tcx>(
256256
infer::HigherRankedType,
257257
tcx.fn_sig(impl_m.def_id),
258258
);
259+
let unnormalized_impl_fty = tcx.mk_fn_ptr(ty::Binder::dummy(unnormalized_impl_sig));
260+
261+
// We need to check that the impl's args are well-formed given
262+
// the hybrid param-env (impl + trait method where-clauses).
263+
ocx.register_obligation(traits::Obligation::new(
264+
tcx,
265+
cause.clone(),
266+
param_env,
267+
ty::Binder::dummy(ty::PredicateKind::WellFormed(
268+
tcx.mk_fn_ptr(ty::Binder::dummy(unnormalized_impl_sig)).into(),
269+
)),
270+
));
259271

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

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

303-
// Finally, we need to check that the impl's args are well-formed given
304-
// the hybrid param-env (impl + trait method where-clauses).
305-
for (unnormalized_arg, arg) in
306-
std::iter::zip(unnormalized_impl_sig.inputs_and_output, impl_sig.inputs_and_output)
307-
{
308-
ocx.register_obligation(traits::Obligation::new(
309-
tcx,
310-
cause.clone(),
311-
param_env,
312-
ty::Binder::dummy(ty::PredicateKind::WellFormed(unnormalized_arg.into())),
313-
));
314-
ocx.register_obligation(traits::Obligation::new(
315-
tcx,
316-
cause.clone(),
317-
param_env,
318-
ty::Binder::dummy(ty::PredicateKind::WellFormed(arg.into())),
319-
));
320-
}
321-
322314
// Check that all obligations are satisfied by the implementation's
323315
// version.
324316
let errors = ocx.select_all_or_error();
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
trait Project {
2+
type Ty;
3+
}
4+
impl Project for &'_ &'_ () {
5+
type Ty = ();
6+
}
7+
trait Trait {
8+
fn get<'s>(s: &'s str, _: ()) -> &'static str;
9+
}
10+
impl Trait for () {
11+
fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
12+
//~^ ERROR cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
13+
s
14+
}
15+
}
16+
fn main() {
17+
let val = <() as Trait>::get(&String::from("blah blah blah"), ());
18+
println!("{}", val);
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
error[E0495]: cannot infer an appropriate lifetime for lifetime parameter 's in generic type due to conflicting requirements
2+
--> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
3+
|
4+
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
note: first, the lifetime cannot outlive the lifetime `'s` as defined here...
8+
--> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:12
9+
|
10+
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
11+
| ^^
12+
note: ...so that the method type is compatible with trait
13+
--> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
14+
|
15+
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
16+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
17+
= note: expected `fn(&'s str, ()) -> &'static str`
18+
found `fn(&str, ()) -> &'static str`
19+
= note: but, the lifetime must be valid for the static lifetime...
20+
note: ...so that the reference type `&'static &()` does not outlive the data it points at
21+
--> $DIR/impl-implied-bounds-compatibility-unnormalized.rs:11:5
22+
|
23+
LL | fn get<'s>(s: &'s str, _: <&'static &'s () as Project>::Ty) -> &'static str {
24+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
25+
26+
error: aborting due to previous error
27+
28+
For more information about this error, try `rustc --explain E0495`.

0 commit comments

Comments
 (0)