Skip to content

Commit

Permalink
Don't treat unnormalized function arguments as well-formed
Browse files Browse the repository at this point in the history
  • Loading branch information
jackh726 authored and Mark-Simulacrum committed Nov 29, 2021
1 parent 7f56b9a commit a9174cf
Show file tree
Hide file tree
Showing 8 changed files with 52 additions and 46 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -258,7 +258,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))
Expand Down Expand Up @@ -286,10 +285,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();

Expand Down
7 changes: 1 addition & 6 deletions compiler/rustc_typeck/src/check/compare_method.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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));

Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_typeck/src/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
5 changes: 0 additions & 5 deletions compiler/rustc_typeck/src/check/wfcheck.rs
Original file line number Diff line number Diff line change
Expand Up @@ -960,11 +960,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`
Expand Down
14 changes: 14 additions & 0 deletions src/test/ui/fn/implied-bounds-unnorm-associated-type.nll.stderr
Original file line number Diff line number Diff line change
@@ -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 changes: 22 additions & 0 deletions src/test/ui/fn/implied-bounds-unnorm-associated-type.rs
Original file line number Diff line number Diff line change
@@ -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 changes: 13 additions & 0 deletions src/test/ui/fn/implied-bounds-unnorm-associated-type.stderr
Original file line number Diff line number Diff line change
@@ -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`.
30 changes: 0 additions & 30 deletions src/test/ui/generic-associated-types/issue-87748.rs

This file was deleted.

0 comments on commit a9174cf

Please sign in to comment.