Skip to content

Commit

Permalink
Rollup merge of rust-lang#111246 - lcnr:no-escaping-bound-vars, r=com…
Browse files Browse the repository at this point in the history
…piler-errors

forbid escaping bound vars in combine

removes the `CollectAllMismatches` in favor of a slightly more manual approach.

r? types cc `@estebank`
  • Loading branch information
matthiaskrgr authored May 5, 2023
2 parents d7a91f0 + 6691c4c commit c83dbc5
Show file tree
Hide file tree
Showing 4 changed files with 46 additions and 131 deletions.
22 changes: 8 additions & 14 deletions compiler/rustc_infer/src/infer/combine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,8 @@ impl<'tcx> InferCtxt<'tcx> {
R: ObligationEmittingRelation<'tcx>,
{
let a_is_expected = relation.a_is_expected();
debug_assert!(!a.has_escaping_bound_vars());
debug_assert!(!b.has_escaping_bound_vars());

match (a.kind(), b.kind()) {
// Relate integral variables to other types
Expand Down Expand Up @@ -163,6 +165,8 @@ impl<'tcx> InferCtxt<'tcx> {
R: ObligationEmittingRelation<'tcx>,
{
debug!("{}.consts({:?}, {:?})", relation.tag(), a, b);
debug_assert!(!a.has_escaping_bound_vars());
debug_assert!(!b.has_escaping_bound_vars());
if a == b {
return Ok(a);
}
Expand Down Expand Up @@ -238,22 +242,12 @@ impl<'tcx> InferCtxt<'tcx> {
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
return self.unify_const_variable(vid, a);
}
(ty::ConstKind::Unevaluated(..), _) if self.tcx.lazy_normalization() => {
// FIXME(#59490): Need to remove the leak check to accommodate
// escaping bound variables here.
if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
relation.register_const_equate_obligation(a, b);
}
(ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
if self.tcx.lazy_normalization() =>
{
relation.register_const_equate_obligation(a, b);
return Ok(b);
}
(_, ty::ConstKind::Unevaluated(..)) if self.tcx.lazy_normalization() => {
// FIXME(#59490): Need to remove the leak check to accommodate
// escaping bound variables here.
if !a.has_escaping_bound_vars() && !b.has_escaping_bound_vars() {
relation.register_const_equate_obligation(a, b);
}
return Ok(a);
}
_ => {}
}

Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
mod ambiguity;
pub mod method_chain;
pub mod on_unimplemented;
pub mod suggestions;

Expand Down Expand Up @@ -559,6 +558,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
suggest_increasing_limit,
|err| {
self.note_obligation_cause_code(
obligation.cause.body_id,
err,
predicate,
obligation.param_env,
Expand Down Expand Up @@ -1431,6 +1431,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
| ObligationCauseCode::ExprItemObligation(..) = code
{
self.note_obligation_cause_code(
error.obligation.cause.body_id,
&mut diag,
error.obligation.predicate,
error.obligation.param_env,
Expand Down Expand Up @@ -2544,6 +2545,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// message, and fall back to regular note otherwise.
if !self.maybe_note_obligation_cause_for_async_await(err, obligation) {
self.note_obligation_cause_code(
obligation.cause.body_id,
err,
obligation.predicate,
obligation.param_env,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,9 @@ use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Node};
use rustc_hir::{Expr, HirId};
use rustc_infer::infer::error_reporting::TypeErrCtxt;
use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
use rustc_infer::infer::{InferOk, LateBoundRegionConversionTime};
use rustc_infer::infer::{DefineOpaqueTypes, InferOk, LateBoundRegionConversionTime};
use rustc_middle::hir::map;
use rustc_middle::ty::error::TypeError::{self, Sorts};
use rustc_middle::ty::relate::TypeRelation;
use rustc_middle::ty::{
self, suggest_arbitrary_trait_bound, suggest_constraining_type_param, AdtKind,
GeneratorDiagnosticData, GeneratorInteriorTypeCause, Infer, InferTy, InternalSubsts,
Expand All @@ -39,9 +38,9 @@ use rustc_span::def_id::LocalDefId;
use rustc_span::symbol::{sym, Ident, Symbol};
use rustc_span::{BytePos, DesugaringKind, ExpnKind, MacroKind, Span, DUMMY_SP};
use rustc_target::spec::abi;
use std::iter;
use std::ops::Deref;

use super::method_chain::CollectAllMismatches;
use super::InferCtxtPrivExt;
use crate::infer::InferCtxtExt as _;
use crate::traits::query::evaluate_obligation::InferCtxtExt as _;
Expand Down Expand Up @@ -319,6 +318,7 @@ pub trait TypeErrCtxtExt<'tcx> {

fn note_obligation_cause_code<T>(
&self,
body_id: LocalDefId,
err: &mut Diagnostic,
predicate: T,
param_env: ty::ParamEnv<'tcx>,
Expand Down Expand Up @@ -359,8 +359,9 @@ pub trait TypeErrCtxtExt<'tcx> {
);
fn note_function_argument_obligation(
&self,
arg_hir_id: HirId,
body_id: LocalDefId,
err: &mut Diagnostic,
arg_hir_id: HirId,
parent_code: &ObligationCauseCode<'tcx>,
param_env: ty::ParamEnv<'tcx>,
predicate: ty::Predicate<'tcx>,
Expand Down Expand Up @@ -2742,6 +2743,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// bound that introduced the obligation (e.g. `T: Send`).
debug!(?next_code);
self.note_obligation_cause_code(
obligation.cause.body_id,
err,
obligation.predicate,
obligation.param_env,
Expand All @@ -2753,6 +2755,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {

fn note_obligation_cause_code<T>(
&self,
body_id: LocalDefId,
err: &mut Diagnostic,
predicate: T,
param_env: ty::ParamEnv<'tcx>,
Expand Down Expand Up @@ -3152,6 +3155,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// #74711: avoid a stack overflow
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
body_id,
err,
parent_predicate,
param_env,
Expand All @@ -3163,6 +3167,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
} else {
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
body_id,
err,
parent_predicate,
param_env,
Expand Down Expand Up @@ -3292,6 +3297,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// #74711: avoid a stack overflow
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
body_id,
err,
parent_predicate,
param_env,
Expand All @@ -3307,6 +3313,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// #74711: avoid a stack overflow
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
body_id,
err,
parent_predicate,
param_env,
Expand All @@ -3323,15 +3330,17 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
..
} => {
self.note_function_argument_obligation(
arg_hir_id,
body_id,
err,
arg_hir_id,
parent_code,
param_env,
predicate,
call_hir_id,
);
ensure_sufficient_stack(|| {
self.note_obligation_cause_code(
body_id,
err,
predicate,
param_env,
Expand Down Expand Up @@ -3553,8 +3562,9 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
}
fn note_function_argument_obligation(
&self,
arg_hir_id: HirId,
body_id: LocalDefId,
err: &mut Diagnostic,
arg_hir_id: HirId,
parent_code: &ObligationCauseCode<'tcx>,
param_env: ty::ParamEnv<'tcx>,
failed_pred: ty::Predicate<'tcx>,
Expand Down Expand Up @@ -3587,7 +3597,6 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
// to an associated type (as seen from `trait_pred`) in the predicate. Like in
// trait_pred `S: Sum<<Self as Iterator>::Item>` and predicate `i32: Sum<&()>`
let mut type_diffs = vec![];

if let ObligationCauseCode::ExprBindingObligation(def_id, _, _, idx) = parent_code.deref()
&& let Some(node_substs) = typeck_results.node_substs_opt(call_hir_id)
&& let where_clauses = self.tcx.predicates_of(def_id).instantiate(self.tcx, node_substs)
Expand All @@ -3596,14 +3605,26 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
if let Some(where_pred) = where_pred.to_opt_poly_trait_pred()
&& let Some(failed_pred) = failed_pred.to_opt_poly_trait_pred()
{
let mut c = CollectAllMismatches {
infcx: self.infcx,
param_env,
errors: vec![],
let where_pred = self.instantiate_binder_with_placeholders(where_pred);
let failed_pred = self.instantiate_binder_with_fresh_vars(
expr.span,
LateBoundRegionConversionTime::FnCall,
failed_pred
);

let zipped =
iter::zip(where_pred.trait_ref.substs, failed_pred.trait_ref.substs);
for (expected, actual) in zipped {
self.probe(|_| {
match self
.at(&ObligationCause::misc(expr.span, body_id), param_env)
.eq(DefineOpaqueTypes::No, expected, actual)
{
Ok(_) => (), // We ignore nested obligations here for now.
Err(err) => type_diffs.push(err),
}
})
};
if let Ok(_) = c.relate(where_pred, failed_pred) {
type_diffs = c.errors;
}
} else if let Some(where_pred) = where_pred.to_opt_poly_projection_pred()
&& let Some(failed_pred) = failed_pred.to_opt_poly_projection_pred()
&& let Some(found) = failed_pred.skip_binder().term.ty()
Expand Down

0 comments on commit c83dbc5

Please sign in to comment.