mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-25 16:24:46 +00:00
Don't treat unnormalized function arguments as well-formed
This commit is contained in:
parent
eee8b9c7ba
commit
eeaa215f85
@ -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();
|
||||
|
||||
|
@ -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));
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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`
|
||||
|
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…
Reference in New Issue
Block a user