Rollup merge of #91243 - jackh726:issue-91068, r=nikomatsakis
Don't treat unnormalized function arguments as well-formed Partial revert of #88312 r? ``@pnkfelix`` cc ``@nikomatsakis``
This commit is contained in:
commit
6e7cf2e88b
8 changed files with 52 additions and 46 deletions
|
@ -256,7 +256,6 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
|
||||||
debug!("build: input_or_output={:?}", ty);
|
debug!("build: input_or_output={:?}", ty);
|
||||||
// We add implied bounds from both the unnormalized and normalized ty
|
// We add implied bounds from both the unnormalized and normalized ty
|
||||||
// See issue #87748
|
// See issue #87748
|
||||||
let constraints_implied_1 = self.add_implied_bounds(ty);
|
|
||||||
let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
|
let TypeOpOutput { output: norm_ty, constraints: constraints1, .. } = self
|
||||||
.param_env
|
.param_env
|
||||||
.and(type_op::normalize::Normalize::new(ty))
|
.and(type_op::normalize::Normalize::new(ty))
|
||||||
|
@ -284,10 +283,9 @@ impl UniversalRegionRelationsBuilder<'cx, 'tcx> {
|
||||||
// }
|
// }
|
||||||
// ```
|
// ```
|
||||||
// Both &Self::Bar and &() are WF
|
// Both &Self::Bar and &() are WF
|
||||||
let constraints_implied_2 =
|
let constraints_implied = self.add_implied_bounds(norm_ty);
|
||||||
if ty != norm_ty { self.add_implied_bounds(norm_ty) } else { None };
|
|
||||||
normalized_inputs_and_output.push(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();
|
.collect();
|
||||||
|
|
||||||
|
|
|
@ -264,14 +264,9 @@ fn compare_predicate_entailment<'tcx>(
|
||||||
// First liberate late bound regions and subst placeholders
|
// 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 = 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);
|
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 =
|
let trait_sig =
|
||||||
inh.normalize_associated_types_in(impl_m_span, impl_m_hir_id, param_env, 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.
|
// Add the resulting inputs and output as well-formed.
|
||||||
// This probably isn't strictly necessary.
|
|
||||||
wf_tys.extend(trait_sig.inputs_and_output.iter());
|
wf_tys.extend(trait_sig.inputs_and_output.iter());
|
||||||
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
|
let trait_fty = tcx.mk_fn_ptr(ty::Binder::dummy(trait_sig));
|
||||||
|
|
||||||
|
|
|
@ -391,7 +391,6 @@ fn typeck_with_fallback<'tcx>(
|
||||||
let mut wf_tys = FxHashSet::default();
|
let mut wf_tys = FxHashSet::default();
|
||||||
// Compute the fty from point of view of inside the fn.
|
// 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);
|
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(
|
let fn_sig = inh.normalize_associated_types_in(
|
||||||
body.value.span,
|
body.value.span,
|
||||||
body_id.hir_id,
|
body_id.hir_id,
|
||||||
|
|
|
@ -1334,11 +1334,6 @@ fn check_fn_or_method<'fcx, 'tcx>(
|
||||||
) {
|
) {
|
||||||
let sig = fcx.tcx.liberate_late_bound_regions(def_id, sig);
|
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
|
// Normalize the input and output types one at a time, using a different
|
||||||
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
|
// `WellFormedLoc` for each. We cannot call `normalize_associated_types`
|
||||||
// on the entire `FnSig`, since this would use the same `WellFormedLoc`
|
// on the entire `FnSig`, since this would use the same `WellFormedLoc`
|
||||||
|
|
|
@ -0,0 +1,14 @@
|
||||||
|
error: lifetime may not live long enough
|
||||||
|
--> $DIR/implied-bounds-unnorm-associated-type.rs:14:5
|
||||||
|
|
|
||||||
|
LL | fn f<'a, 'b>(s: &'b str, _: <&'a &'b () as Trait>::Type) -> &'a str {
|
||||||
|
| -- -- lifetime `'b` defined here
|
||||||
|
| |
|
||||||
|
| lifetime `'a` defined here
|
||||||
|
LL | s
|
||||||
|
| ^ returning this value requires that `'b` must outlive `'a`
|
||||||
|
|
|
||||||
|
= help: consider adding the following bound: `'b: 'a`
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
22
src/test/ui/fn/implied-bounds-unnorm-associated-type.rs
Normal file
22
src/test/ui/fn/implied-bounds-unnorm-associated-type.rs
Normal 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);
|
||||||
|
}
|
13
src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr
Normal file
13
src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr
Normal 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`.
|
|
@ -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 () {}
|
|
Loading…
Add table
Add a link
Reference in a new issue