Don't treat unnormalized function arguments as well-formed

This commit is contained in:
jackh726 2021-11-25 21:16:27 -05:00
parent eee8b9c7ba
commit eeaa215f85
7 changed files with 38 additions and 46 deletions

View file

@ -256,7 +256,6 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
debug!("build: input_or_output={:?}", ty);
// We add implied bounds from both the unnormalized and normalized ty
// See issue #87748
let constraints_implied_1 = self.add_implied_bounds(ty);
let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
.param_env
.and(type_op::normalize::Normalize::new(ty))
@ -284,10 +283,9 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
// }
// ```
// Both &Self::Bar and &() are WF
let constraints_implied_2 =
if ty != norm_ty { self.add_implied_bounds(norm_ty) } else { None };
let constraints_implied = self.add_implied_bounds(norm_ty);
normalized_inputs_and_output.push(norm_ty);
constraints1.into_iter().chain(constraints_implied_1).chain(constraints_implied_2)
constraints1.into_iter().chain(constraints_implied)
})
.collect();

View file

@ -266,14 +266,9 @@ fn compare_predicate_entailment<'tcx>(
// First liberate late bound regions and subst placeholders
let trait_sig = tcx.liberate_late_bound_regions(impl_m.def_id, tcx.fn_sig(trait_m.def_id));
let trait_sig = trait_sig.subst(tcx, trait_to_placeholder_substs);
// Next, add all inputs and output as well-formed tys. Importantly,
// we have to do this before normalization, since the normalized ty may
// not contain the input parameters. See issue #87748.
wf_tys.extend(trait_sig.inputs_and_output.iter());
let trait_sig =
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, trait_sig);
// Also add the resulting inputs and output as well-formed.
// This probably isn't strictly necessary.
// Add the resulting inputs and output as well-formed.
wf_tys.extend(trait_sig.inputs_and_output.iter());
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));

View file

@ -391,7 +391,6 @@ fn typeck_with_fallback<'tcx>(
let mut wf_tys = FxHashSet::default();
// Compute the fty from point of view of inside the fn.
let fn_sig = tcx.liberate_late_bound_regions(def_id.to_def_id(), fn_sig);
wf_tys.extend(fn_sig.inputs_and_output.iter());
let fn_sig = inh.normalize_associated_types_in(
body.value.span,
body_id.hir_id,

View file

@ -1322,11 +1322,6 @@ fn check_fn_or_method<'fcx, 'tcx>(
) {
let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);
// Unnormalized types in signature are WF too
implied_bounds.extend(sig.inputs());
// FIXME(#27579) return types should not be implied bounds
implied_bounds.insert(sig.output());
// Normalize the input and output types one at a time, using a different
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
// on the entire `FnSig`, since this would use the same `WellFormedLoc`

View file

@ -0,0 +1,22 @@
// check-fail
// See issue #91068. Types in the substs of an associated type can't be implied
// to be WF, since they don't actually have to be constructed.
trait Trait {
type Type;
}
impl<T> Trait for T {
type Type = ();
}
fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str {
s //~ ERROR lifetime mismatch [E0623]
}
fn main() {
let x = String::from("Hello World!");
let y = f(&x, ());
drop(x);
println!("{}", y);
}

View file

@ -0,0 +1,13 @@
error[E0623]: lifetime mismatch
--> $DIR/implied-bounds-unnorm-associated-type.rs:14:5
|
LL | fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str {
| ------- ----------
| |
| these two types are declared with different lifetimes...
LL | s
| ^ ...but data from `s` flows here
error: aborting due to previous error
For more information about this error, try `rustc --explain E0623`.

View file

@ -1,30 +0,0 @@
// Checks that we properly add implied bounds from unnormalized projections in
// inputs when typechecking functions.
// check-pass
#![feature(generic_associated_types)]
trait MyTrait {
type Assoc<'a, 'b> where 'b: 'a;
fn do_sth(arg: Self::Assoc<'_, '_>);
}
struct A;
struct B;
struct C;
impl MyTrait for A {
type Assoc<'a, 'b> where 'b: 'a = u32;
fn do_sth(_: u32) {}
}
impl MyTrait for B {
type Assoc<'a, 'b> where 'b: 'a = u32;
fn do_sth(_: Self::Assoc<'_, '_>) {}
}
impl MyTrait for C {
type Assoc<'a, 'b> where 'b: 'a = u32;
fn do_sth(_: Self::Assoc<'static, 'static>) {}
}
fn main () {}