summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_infer
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_infer')
-rw-r--r--compiler/rustc_infer/messages.ftl6
-rw-r--r--compiler/rustc_infer/src/errors/mod.rs21
-rw-r--r--compiler/rustc_infer/src/errors/note_and_explain.rs7
-rw-r--r--compiler/rustc_infer/src/infer/at.rs23
-rw-r--r--compiler/rustc_infer/src/infer/canonical/canonicalizer.rs17
-rw-r--r--compiler/rustc_infer/src/infer/canonical/mod.rs6
-rw-r--r--compiler/rustc_infer/src/infer/combine.rs69
-rw-r--r--compiler/rustc_infer/src/infer/equate.rs20
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/mod.rs36
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs39
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs2
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs6
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs14
-rw-r--r--compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs20
-rw-r--r--compiler/rustc_infer/src/infer/free_regions.rs9
-rw-r--r--compiler/rustc_infer/src/infer/freshen.rs15
-rw-r--r--compiler/rustc_infer/src/infer/generalize.rs1
-rw-r--r--compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs91
-rw-r--r--compiler/rustc_infer/src/infer/mod.rs92
-rw-r--r--compiler/rustc_infer/src/infer/outlives/components.rs2
-rw-r--r--compiler/rustc_infer/src/infer/sub.rs19
-rw-r--r--compiler/rustc_infer/src/infer/undo_log.rs3
23 files changed, 293 insertions, 227 deletions
diff --git a/compiler/rustc_infer/messages.ftl b/compiler/rustc_infer/messages.ftl
index 4d0e77063..46558997f 100644
--- a/compiler/rustc_infer/messages.ftl
+++ b/compiler/rustc_infer/messages.ftl
@@ -198,6 +198,10 @@ infer_nothing = {""}
infer_oc_cant_coerce = cannot coerce intrinsics to function pointers
infer_oc_closure_selfref = closure/generator type that references itself
infer_oc_const_compat = const not compatible with trait
+infer_oc_fn_lang_correct_type = {$lang_item_name ->
+ [panic_impl] `#[panic_handler]`
+ *[lang_item_name] lang item `{$lang_item_name}`
+ } function has wrong type
infer_oc_fn_main_correct_type = `main` function has wrong type
infer_oc_fn_start_correct_type = `#[start]` function has wrong type
infer_oc_generic = mismatched types
@@ -337,6 +341,7 @@ infer_subtype = ...so that the {$requirement ->
[no_else] `if` missing an `else` returns `()`
[fn_main_correct_type] `main` function has the correct type
[fn_start_correct_type] `#[start]` function has the correct type
+ [fn_lang_correct_type] lang item function has the correct type
[intrinsic_correct_type] intrinsic has the correct type
[method_correct_type] method receiver has the correct type
*[other] types are compatible
@@ -350,6 +355,7 @@ infer_subtype_2 = ...so that {$requirement ->
[no_else] `if` missing an `else` returns `()`
[fn_main_correct_type] `main` function has the correct type
[fn_start_correct_type] `#[start]` function has the correct type
+ [fn_lang_correct_type] lang item function has the correct type
[intrinsic_correct_type] intrinsic has the correct type
[method_correct_type] method receiver has the correct type
*[other] types are compatible
diff --git a/compiler/rustc_infer/src/errors/mod.rs b/compiler/rustc_infer/src/errors/mod.rs
index a7e045e1e..ad4525c92 100644
--- a/compiler/rustc_infer/src/errors/mod.rs
+++ b/compiler/rustc_infer/src/errors/mod.rs
@@ -14,8 +14,7 @@ use rustc_span::{symbol::Ident, BytePos, Span};
use crate::fluent_generated as fluent;
use crate::infer::error_reporting::{
- need_type_info::{GeneratorKindAsDiagArg, UnderspecifiedArgKind},
- nice_region_error::placeholder_error::Highlighted,
+ need_type_info::UnderspecifiedArgKind, nice_region_error::placeholder_error::Highlighted,
ObligationCauseAsDiagArg,
};
@@ -86,16 +85,6 @@ pub struct AmbiguousReturn<'a> {
pub multi_suggestions: Vec<SourceKindMultiSuggestion<'a>>,
}
-#[derive(Diagnostic)]
-#[diag(infer_need_type_info_in_generator, code = "E0698")]
-pub struct NeedTypeInfoInGenerator<'a> {
- #[primary_span]
- pub span: Span,
- pub generator_kind: GeneratorKindAsDiagArg,
- #[subdiagnostic]
- pub bad_label: InferenceBadError<'a>,
-}
-
// Used when a better one isn't available
#[derive(Subdiagnostic)]
#[label(infer_label_bad)]
@@ -1463,6 +1452,14 @@ pub enum ObligationCauseFailureCode {
#[subdiagnostic]
subdiags: Vec<TypeErrorAdditionalDiags>,
},
+ #[diag(infer_oc_fn_lang_correct_type, code = "E0308")]
+ FnLangCorrectType {
+ #[primary_span]
+ span: Span,
+ #[subdiagnostic]
+ subdiags: Vec<TypeErrorAdditionalDiags>,
+ lang_item_name: Symbol,
+ },
#[diag(infer_oc_intrinsic_correct_type, code = "E0308")]
IntrinsicCorrectType {
#[primary_span]
diff --git a/compiler/rustc_infer/src/errors/note_and_explain.rs b/compiler/rustc_infer/src/errors/note_and_explain.rs
index bd168f047..9276bb0a7 100644
--- a/compiler/rustc_infer/src/errors/note_and_explain.rs
+++ b/compiler/rustc_infer/src/errors/note_and_explain.rs
@@ -56,11 +56,8 @@ impl<'a> DescriptionCtx<'a> {
(Some(span), "as_defined", name.to_string())
}
}
- ty::BrAnon(span) => {
- let span = match span {
- Some(_) => span,
- None => Some(tcx.def_span(scope)),
- };
+ ty::BrAnon => {
+ let span = Some(tcx.def_span(scope));
(span, "defined_here", String::new())
}
_ => {
diff --git a/compiler/rustc_infer/src/infer/at.rs b/compiler/rustc_infer/src/infer/at.rs
index 6d5db3336..2797d0797 100644
--- a/compiler/rustc_infer/src/infer/at.rs
+++ b/compiler/rustc_infer/src/infer/at.rs
@@ -478,7 +478,28 @@ impl<'tcx> ToTrace<'tcx> for ty::FnSig<'tcx> {
a: Self,
b: Self,
) -> TypeTrace<'tcx> {
- TypeTrace { cause: cause.clone(), values: Sigs(ExpectedFound::new(a_is_expected, a, b)) }
+ TypeTrace {
+ cause: cause.clone(),
+ values: PolySigs(ExpectedFound::new(
+ a_is_expected,
+ ty::Binder::dummy(a),
+ ty::Binder::dummy(b),
+ )),
+ }
+ }
+}
+
+impl<'tcx> ToTrace<'tcx> for ty::PolyFnSig<'tcx> {
+ fn to_trace(
+ cause: &ObligationCause<'tcx>,
+ a_is_expected: bool,
+ a: Self,
+ b: Self,
+ ) -> TypeTrace<'tcx> {
+ TypeTrace {
+ cause: cause.clone(),
+ values: PolySigs(ExpectedFound::new(a_is_expected, a, b)),
+ }
}
}
diff --git a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
index 9d7a9fefd..4124c9ead 100644
--- a/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
+++ b/compiler/rustc_infer/src/infer/canonical/canonicalizer.rs
@@ -459,7 +459,6 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
ty::Closure(..)
| ty::Generator(..)
| ty::GeneratorWitness(..)
- | ty::GeneratorWitnessMIR(..)
| ty::Bool
| ty::Char
| ty::Int(..)
@@ -522,6 +521,17 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
}
}
}
+ ty::ConstKind::Infer(InferConst::EffectVar(vid)) => {
+ match self.infcx.probe_effect_var(vid) {
+ Some(value) => return self.fold_const(value.as_const(self.infcx.tcx)),
+ None => {
+ return self.canonicalize_const_var(
+ CanonicalVarInfo { kind: CanonicalVarKind::Effect },
+ ct,
+ );
+ }
+ }
+ }
ty::ConstKind::Infer(InferConst::Fresh(_)) => {
bug!("encountered a fresh const during canonicalization")
}
@@ -690,7 +700,8 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
.iter()
.map(|v| CanonicalVarInfo {
kind: match v.kind {
- CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float) => {
+ CanonicalVarKind::Ty(CanonicalTyVarKind::Int | CanonicalTyVarKind::Float)
+ | CanonicalVarKind::Effect => {
return *v;
}
CanonicalVarKind::Ty(CanonicalTyVarKind::General(u)) => {
@@ -764,7 +775,7 @@ impl<'cx, 'tcx> Canonicalizer<'cx, 'tcx> {
r: ty::Region<'tcx>,
) -> ty::Region<'tcx> {
let var = self.canonical_var(info, r.into());
- let br = ty::BoundRegion { var, kind: ty::BrAnon(None) };
+ let br = ty::BoundRegion { var, kind: ty::BrAnon };
ty::Region::new_late_bound(self.interner(), self.binder_index, br)
}
diff --git a/compiler/rustc_infer/src/infer/canonical/mod.rs b/compiler/rustc_infer/src/infer/canonical/mod.rs
index 8ca2e4030..41787ee29 100644
--- a/compiler/rustc_infer/src/infer/canonical/mod.rs
+++ b/compiler/rustc_infer/src/infer/canonical/mod.rs
@@ -151,7 +151,11 @@ impl<'tcx> InferCtxt<'tcx> {
universe_map(ui),
)
.into(),
-
+ CanonicalVarKind::Effect => {
+ let vid = self.inner.borrow_mut().effect_unification_table().new_key(None);
+ ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(vid), self.tcx.types.bool)
+ .into()
+ }
CanonicalVarKind::PlaceholderConst(ty::PlaceholderConst { universe, bound }, ty) => {
let universe_mapped = universe_map(universe);
let placeholder_mapped = ty::PlaceholderConst { universe: universe_mapped, bound };
diff --git a/compiler/rustc_infer/src/infer/combine.rs b/compiler/rustc_infer/src/infer/combine.rs
index ddc8e7e50..ee13eb027 100644
--- a/compiler/rustc_infer/src/infer/combine.rs
+++ b/compiler/rustc_infer/src/infer/combine.rs
@@ -30,7 +30,7 @@ use super::{DefineOpaqueTypes, InferCtxt, TypeTrace};
use crate::infer::generalize::{self, CombineDelegate, Generalization};
use crate::traits::{Obligation, PredicateObligations};
use rustc_middle::infer::canonical::OriginalQueryValues;
-use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
+use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVarValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
use rustc_middle::ty::error::{ExpectedFound, TypeError};
use rustc_middle::ty::relate::{RelateResult, TypeRelation};
@@ -91,7 +91,7 @@ impl<'tcx> InferCtxt<'tcx> {
.borrow_mut()
.float_unification_table()
.unify_var_var(a_id, b_id)
- .map_err(|e| float_unification_error(relation.a_is_expected(), e))?;
+ .map_err(|e| float_unification_error(a_is_expected, e))?;
Ok(a)
}
(&ty::Infer(ty::FloatVar(v_id)), &ty::Float(v)) => {
@@ -210,10 +210,30 @@ impl<'tcx> InferCtxt<'tcx> {
return Ok(a);
}
+ (
+ ty::ConstKind::Infer(InferConst::EffectVar(a_vid)),
+ ty::ConstKind::Infer(InferConst::EffectVar(b_vid)),
+ ) => {
+ self.inner
+ .borrow_mut()
+ .effect_unification_table()
+ .unify_var_var(a_vid, b_vid)
+ .map_err(|a| effect_unification_error(self.tcx, relation.a_is_expected(), a))?;
+ return Ok(a);
+ }
+
// All other cases of inference with other variables are errors.
- (ty::ConstKind::Infer(InferConst::Var(_)), ty::ConstKind::Infer(_))
- | (ty::ConstKind::Infer(_), ty::ConstKind::Infer(InferConst::Var(_))) => {
- bug!("tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var)")
+ (
+ ty::ConstKind::Infer(InferConst::Var(_) | InferConst::EffectVar(_)),
+ ty::ConstKind::Infer(_),
+ )
+ | (
+ ty::ConstKind::Infer(_),
+ ty::ConstKind::Infer(InferConst::Var(_) | InferConst::EffectVar(_)),
+ ) => {
+ bug!(
+ "tried to combine ConstKind::Infer/ConstKind::Infer(InferConst::Var): {a:?} and {b:?}"
+ )
}
(ty::ConstKind::Infer(InferConst::Var(vid)), _) => {
@@ -223,6 +243,23 @@ impl<'tcx> InferCtxt<'tcx> {
(_, ty::ConstKind::Infer(InferConst::Var(vid))) => {
return self.unify_const_variable(vid, a, relation.param_env());
}
+
+ (ty::ConstKind::Infer(InferConst::EffectVar(vid)), _) => {
+ return self.unify_effect_variable(
+ relation.a_is_expected(),
+ vid,
+ EffectVarValue::Const(b),
+ );
+ }
+
+ (_, ty::ConstKind::Infer(InferConst::EffectVar(vid))) => {
+ return self.unify_effect_variable(
+ !relation.a_is_expected(),
+ vid,
+ EffectVarValue::Const(a),
+ );
+ }
+
(ty::ConstKind::Unevaluated(..), _) | (_, ty::ConstKind::Unevaluated(..))
if self.tcx.features().generic_const_exprs || self.next_trait_solver() =>
{
@@ -340,6 +377,20 @@ impl<'tcx> InferCtxt<'tcx> {
.map_err(|e| float_unification_error(vid_is_expected, e))?;
Ok(Ty::new_float(self.tcx, val))
}
+
+ fn unify_effect_variable(
+ &self,
+ vid_is_expected: bool,
+ vid: ty::EffectVid<'tcx>,
+ val: EffectVarValue<'tcx>,
+ ) -> RelateResult<'tcx, ty::Const<'tcx>> {
+ self.inner
+ .borrow_mut()
+ .effect_unification_table()
+ .unify_var_value(vid, Some(val))
+ .map_err(|e| effect_unification_error(self.tcx, vid_is_expected, e))?;
+ Ok(val.as_const(self.tcx))
+ }
}
impl<'infcx, 'tcx> CombineFields<'infcx, 'tcx> {
@@ -493,3 +544,11 @@ fn float_unification_error<'tcx>(
let (ty::FloatVarValue(a), ty::FloatVarValue(b)) = v;
TypeError::FloatMismatch(ExpectedFound::new(a_is_expected, a, b))
}
+
+fn effect_unification_error<'tcx>(
+ _tcx: TyCtxt<'tcx>,
+ _a_is_expected: bool,
+ (_a, _b): (EffectVarValue<'tcx>, EffectVarValue<'tcx>),
+) -> TypeError<'tcx> {
+ bug!("unexpected effect unification error")
+}
diff --git a/compiler/rustc_infer/src/infer/equate.rs b/compiler/rustc_infer/src/infer/equate.rs
index 1dbab48fd..665297da2 100644
--- a/compiler/rustc_infer/src/infer/equate.rs
+++ b/compiler/rustc_infer/src/infer/equate.rs
@@ -119,26 +119,6 @@ impl<'tcx> TypeRelation<'tcx> for Equate<'_, '_, 'tcx> {
.obligations,
);
}
- // Optimization of GeneratorWitness relation since we know that all
- // free regions are replaced with bound regions during construction.
- // This greatly speeds up equating of GeneratorWitness.
- (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
- let a_types = infcx.tcx.anonymize_bound_vars(a_types);
- let b_types = infcx.tcx.anonymize_bound_vars(b_types);
- if a_types.bound_vars() == b_types.bound_vars() {
- let (a_types, b_types) = infcx.instantiate_binder_with_placeholders(
- a_types.map_bound(|a_types| (a_types, b_types.skip_binder())),
- );
- for (a, b) in std::iter::zip(a_types, b_types) {
- self.relate(a, b)?;
- }
- } else {
- return Err(ty::error::TypeError::Sorts(ty::relate::expected_found(
- self, a, b,
- )));
- }
- }
-
_ => {
self.fields.infcx.super_combine_tys(self, a, b)?;
}
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
index ac5468f3d..72cfc1337 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs
@@ -242,12 +242,9 @@ fn msg_span_from_named_region<'tcx>(
};
(text, Some(span))
}
- ty::BrAnon(span) => (
+ ty::BrAnon => (
"the anonymous lifetime as defined here".to_string(),
- Some(match span {
- Some(span) => span,
- None => tcx.def_span(scope)
- })
+ Some(tcx.def_span(scope))
),
_ => (
format!("the lifetime `{region}` as defined here"),
@@ -262,11 +259,7 @@ fn msg_span_from_named_region<'tcx>(
..
}) => (format!("the lifetime `{name}` as defined here"), Some(tcx.def_span(def_id))),
ty::RePlaceholder(ty::PlaceholderRegion {
- bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(Some(span)), .. },
- ..
- }) => ("the anonymous lifetime defined here".to_owned(), Some(span)),
- ty::RePlaceholder(ty::PlaceholderRegion {
- bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon(None), .. },
+ bound: ty::BoundRegion { kind: ty::BoundRegionKind::BrAnon, .. },
..
}) => ("an anonymous lifetime".to_owned(), None),
_ => bug!("{:?}", region),
@@ -1616,7 +1609,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
// | expected `()`, found closure
// |
// = note: expected unit type `()`
- // found closure `[closure@$DIR/issue-20862.rs:2:5: 2:14 x:_]`
+ // found closure `{closure@$DIR/issue-20862.rs:2:5: 2:14 x:_}`
//
// Also ignore opaque `Future`s that come from async fns.
if !self.ignore_span.overlaps(span)
@@ -1642,8 +1635,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ValuePairs::Terms(infer::ExpectedFound { expected, found }) => {
match (expected.unpack(), found.unpack()) {
(ty::TermKind::Ty(expected), ty::TermKind::Ty(found)) => {
- let is_simple_err =
- expected.is_simple_text() && found.is_simple_text();
+ let is_simple_err = expected.is_simple_text(self.tcx)
+ && found.is_simple_text(self.tcx);
OpaqueTypesVisitor::visit_expected_found(
self.tcx, expected, found, span,
)
@@ -1660,7 +1653,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
_ => (false, Mismatch::Fixed("type")),
}
}
- ValuePairs::Sigs(infer::ExpectedFound { expected, found }) => {
+ ValuePairs::PolySigs(infer::ExpectedFound { expected, found }) => {
OpaqueTypesVisitor::visit_expected_found(self.tcx, expected, found, span)
.report(diag);
(false, Mismatch::Fixed("signature"))
@@ -1885,7 +1878,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
s
};
- if !(values.expected.is_simple_text() && values.found.is_simple_text())
+ if !(values.expected.is_simple_text(self.tcx) && values.found.is_simple_text(self.tcx))
|| (exp_found.is_some_and(|ef| {
// This happens when the type error is a subset of the expectation,
// like when you have two references but one is `usize` and the other
@@ -2232,15 +2225,12 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
ret => ret,
}
}
- infer::Sigs(exp_found) => {
+ infer::PolySigs(exp_found) => {
let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() {
return None;
}
- let (exp, fnd) = self.cmp_fn_sig(
- &ty::Binder::dummy(exp_found.expected),
- &ty::Binder::dummy(exp_found.found),
- );
+ let (exp, fnd) = self.cmp_fn_sig(&exp_found.expected, &exp_found.found);
Some((exp, fnd, None, None))
}
}
@@ -2927,6 +2917,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
| IfExpression { .. }
| LetElse
| StartFunctionType
+ | LangFunctionType(_)
| IntrinsicType
| MethodReceiver => Error0308,
@@ -2971,6 +2962,9 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
LetElse => ObligationCauseFailureCode::NoDiverge { span, subdiags },
MainFunctionType => ObligationCauseFailureCode::FnMainCorrectType { span },
StartFunctionType => ObligationCauseFailureCode::FnStartCorrectType { span, subdiags },
+ &LangFunctionType(lang_item_name) => {
+ ObligationCauseFailureCode::FnLangCorrectType { span, subdiags, lang_item_name }
+ }
IntrinsicType => ObligationCauseFailureCode::IntrinsicCorrectType { span, subdiags },
MethodReceiver => ObligationCauseFailureCode::MethodCorrectType { span, subdiags },
@@ -3006,6 +3000,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
IfExpressionWithNoElse => "`if` missing an `else` returns `()`",
MainFunctionType => "`main` function has the correct type",
StartFunctionType => "`#[start]` function has the correct type",
+ LangFunctionType(_) => "lang item function has the correct type",
IntrinsicType => "intrinsic has the correct type",
MethodReceiver => "method receiver has the correct type",
_ => "types are compatible",
@@ -3028,6 +3023,7 @@ impl IntoDiagnosticArg for ObligationCauseAsDiagArg<'_> {
IfExpressionWithNoElse => "no_else",
MainFunctionType => "fn_main_correct_type",
StartFunctionType => "fn_start_correct_type",
+ LangFunctionType(_) => "fn_lang_correct_type",
IntrinsicType => "intrinsic_correct_type",
MethodReceiver => "method_correct_type",
_ => "other",
diff --git a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
index f2a3c47bd..a9029a8ce 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/need_type_info.rs
@@ -1,5 +1,5 @@
use crate::errors::{
- AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError, NeedTypeInfoInGenerator,
+ AmbiguousImpl, AmbiguousReturn, AnnotationRequired, InferenceBadError,
SourceKindMultiSuggestion, SourceKindSubdiag,
};
use crate::infer::error_reporting::TypeErrCtxt;
@@ -595,39 +595,6 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
}
}
-impl<'tcx> InferCtxt<'tcx> {
- pub fn need_type_info_err_in_generator(
- &self,
- kind: hir::GeneratorKind,
- span: Span,
- ty: ty::Term<'tcx>,
- ) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
- let ty = self.resolve_vars_if_possible(ty);
- let data = self.extract_inference_diagnostics_data(ty.into(), None);
-
- NeedTypeInfoInGenerator {
- bad_label: data.make_bad_error(span),
- span,
- generator_kind: GeneratorKindAsDiagArg(kind),
- }
- .into_diagnostic(&self.tcx.sess.parse_sess.span_diagnostic)
- }
-}
-
-pub struct GeneratorKindAsDiagArg(pub hir::GeneratorKind);
-
-impl IntoDiagnosticArg for GeneratorKindAsDiagArg {
- fn into_diagnostic_arg(self) -> rustc_errors::DiagnosticArgValue<'static> {
- let kind = match self.0 {
- hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) => "async_block",
- hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Closure) => "async_closure",
- hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn) => "async_fn",
- hir::GeneratorKind::Gen => "generator",
- };
- rustc_errors::DiagnosticArgValue::Str(kind.into())
- }
-}
-
#[derive(Debug)]
struct InferSource<'tcx> {
span: Span,
@@ -951,7 +918,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
//
// See the `need_type_info/issue-103053.rs` test for
// a example.
- if !matches!(path.res, Res::Def(DefKind::TyAlias { .. }, _)) => {
+ if !matches!(path.res, Res::Def(DefKind::TyAlias, _)) => {
if let Some(ty) = self.opt_node_type(expr.hir_id)
&& let ty::Adt(_, args) = ty.kind()
{
@@ -1080,7 +1047,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
) => {
if tcx.res_generics_def_id(path.res) != Some(def.did()) {
match path.res {
- Res::Def(DefKind::TyAlias { .. }, _) => {
+ Res::Def(DefKind::TyAlias, _) => {
// FIXME: Ideally we should support this. For that
// we have to map back from the self type to the
// type alias though. That's difficult.
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
index 07f04ec1e..1b43022f8 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/named_anon_conflict.rs
@@ -61,7 +61,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
let is_impl_item = region_info.is_impl_item;
match br {
- ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon(..) => {}
+ ty::BrNamed(_, kw::UnderscoreLifetime) | ty::BrAnon => {}
_ => {
/* not an anonymous region */
debug!("try_report_named_anon_conflict: not an anonymous region");
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
index f903f7a49..4aec28b05 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_error.rs
@@ -385,7 +385,7 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
let highlight_trait_ref = |trait_ref| Highlighted {
tcx: self.tcx(),
- highlight: RegionHighlightMode::new(self.tcx()),
+ highlight: RegionHighlightMode::default(),
value: trait_ref,
};
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
index 8a78a1956..f5b891253 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/placeholder_relation.rs
@@ -36,15 +36,13 @@ impl<'tcx> NiceRegionError<'_, 'tcx> {
ty::BrNamed(def_id, symbol) => {
(Some(self.tcx().def_span(def_id)), Some(symbol))
}
- ty::BrAnon(span) => (*span, None),
- ty::BrEnv => (None, None),
+ ty::BrAnon | ty::BrEnv => (None, None),
};
let (sup_span, sup_symbol) = match sup_name {
ty::BrNamed(def_id, symbol) => {
(Some(self.tcx().def_span(def_id)), Some(symbol))
}
- ty::BrAnon(span) => (*span, None),
- ty::BrEnv => (None, None),
+ ty::BrAnon | ty::BrEnv => (None, None),
};
let diag = match (sub_span, sup_span, sub_symbol, sup_symbol) {
(Some(sub_span), Some(sup_span), Some(&sub_symbol), Some(&sup_symbol)) => {
diff --git a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
index 12d38ced0..cb51254a1 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/nice_region_error/trait_impl_difference.rs
@@ -35,14 +35,14 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
&& let (Subtype(sup_trace), Subtype(sub_trace)) = (&sup_origin, &sub_origin)
&& let CompareImplItemObligation { trait_item_def_id, .. } = sub_trace.cause.code()
&& sub_trace.values == sup_trace.values
- && let ValuePairs::Sigs(ExpectedFound { expected, found }) = sub_trace.values
+ && let ValuePairs::PolySigs(ExpectedFound { expected, found }) = sub_trace.values
{
// FIXME(compiler-errors): Don't like that this needs `Ty`s, but
// all of the region highlighting machinery only deals with those.
let guar = self.emit_err(
var_origin.span(),
- Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(expected)),
- Ty::new_fn_ptr(self.cx.tcx,ty::Binder::dummy(found)),
+ Ty::new_fn_ptr(self.cx.tcx, expected),
+ Ty::new_fn_ptr(self.cx.tcx, found),
*trait_item_def_id,
);
return Some(guar);
@@ -67,9 +67,9 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
}
impl<'tcx> HighlightBuilder<'tcx> {
- fn build(tcx: TyCtxt<'tcx>, ty: Ty<'tcx>) -> RegionHighlightMode<'tcx> {
+ fn build(ty: Ty<'tcx>) -> RegionHighlightMode<'tcx> {
let mut builder =
- HighlightBuilder { highlight: RegionHighlightMode::new(tcx), counter: 1 };
+ HighlightBuilder { highlight: RegionHighlightMode::default(), counter: 1 };
builder.visit_ty(ty);
builder.highlight
}
@@ -85,12 +85,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
}
}
- let expected_highlight = HighlightBuilder::build(self.tcx(), expected);
+ let expected_highlight = HighlightBuilder::build(expected);
let expected = self
.cx
.extract_inference_diagnostics_data(expected.into(), Some(expected_highlight))
.name;
- let found_highlight = HighlightBuilder::build(self.tcx(), found);
+ let found_highlight = HighlightBuilder::build(found);
let found =
self.cx.extract_inference_diagnostics_data(found.into(), Some(found_highlight)).name;
diff --git a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
index 372539d73..5c3beee28 100644
--- a/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
+++ b/compiler/rustc_infer/src/infer/error_reporting/note_and_explain.rs
@@ -266,12 +266,10 @@ impl<T> Trait<T> for X {
}
}
}
- (ty::FnPtr(_), ty::FnDef(def, _))
- if let hir::def::DefKind::Fn = tcx.def_kind(def) => {
- diag.note(
- "when the arguments and return types match, functions can be coerced \
- to function pointers",
- );
+ (ty::FnPtr(sig), ty::FnDef(def_id, _)) | (ty::FnDef(def_id, _), ty::FnPtr(sig)) => {
+ if tcx.fn_sig(*def_id).skip_binder().unsafety() < sig.unsafety() {
+ diag.note("unsafe functions cannot be coerced into safe function pointers");
+ }
}
_ => {}
}
@@ -618,9 +616,13 @@ fn foo(&self) -> Self::T { String::new() }
for item in &items[..] {
if let hir::AssocItemKind::Type = item.kind {
let assoc_ty = tcx.type_of(item.id.owner_id).instantiate_identity();
-
- if self.infcx.can_eq(param_env, assoc_ty, found) {
- diag.span_label(item.span, "expected this associated type");
+ if let hir::Defaultness::Default { has_value: true } = tcx.defaultness(item.id.owner_id)
+ && self.infcx.can_eq(param_env, assoc_ty, found)
+ {
+ diag.span_label(
+ item.span,
+ "associated type is `default` and may be overridden",
+ );
return true;
}
}
diff --git a/compiler/rustc_infer/src/infer/free_regions.rs b/compiler/rustc_infer/src/infer/free_regions.rs
index 2402a7ea7..ed1a2a117 100644
--- a/compiler/rustc_infer/src/infer/free_regions.rs
+++ b/compiler/rustc_infer/src/infer/free_regions.rs
@@ -4,7 +4,7 @@
//! and use that to decide when one free region outlives another, and so forth.
use rustc_data_structures::transitive_relation::TransitiveRelation;
-use rustc_middle::ty::{Lift, Region, TyCtxt};
+use rustc_middle::ty::{Region, TyCtxt};
/// Combines a `FreeRegionMap` and a `TyCtxt`.
///
@@ -101,10 +101,3 @@ impl<'tcx> FreeRegionMap<'tcx> {
result
}
}
-
-impl<'a, 'tcx> Lift<'tcx> for FreeRegionMap<'a> {
- type Lifted = FreeRegionMap<'tcx>;
- fn lift_to_tcx(self, tcx: TyCtxt<'tcx>) -> Option<FreeRegionMap<'tcx>> {
- self.relation.maybe_map(|fr| tcx.lift(fr)).map(|relation| FreeRegionMap { relation })
- }
-}
diff --git a/compiler/rustc_infer/src/infer/freshen.rs b/compiler/rustc_infer/src/infer/freshen.rs
index 689945d64..0596ce373 100644
--- a/compiler/rustc_infer/src/infer/freshen.rs
+++ b/compiler/rustc_infer/src/infer/freshen.rs
@@ -156,6 +156,21 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for TypeFreshener<'a, 'tcx> {
.known();
self.freshen_const(opt_ct, ty::InferConst::Var(v), ty::InferConst::Fresh, ct.ty())
}
+ ty::ConstKind::Infer(ty::InferConst::EffectVar(v)) => {
+ let opt_ct = self
+ .infcx
+ .inner
+ .borrow_mut()
+ .effect_unification_table()
+ .probe_value(v)
+ .map(|effect| effect.as_const(self.infcx.tcx));
+ self.freshen_const(
+ opt_ct,
+ ty::InferConst::EffectVar(v),
+ ty::InferConst::Fresh,
+ ct.ty(),
+ )
+ }
ty::ConstKind::Infer(ty::InferConst::Fresh(i)) => {
if i >= self.const_freshen_count {
bug!(
diff --git a/compiler/rustc_infer/src/infer/generalize.rs b/compiler/rustc_infer/src/infer/generalize.rs
index cf674d5dd..dd7f8d354 100644
--- a/compiler/rustc_infer/src/infer/generalize.rs
+++ b/compiler/rustc_infer/src/infer/generalize.rs
@@ -403,6 +403,7 @@ where
}
}
}
+ ty::ConstKind::Infer(InferConst::EffectVar(_)) => Ok(c),
// FIXME: remove this branch once `structurally_relate_consts` is fully
// structural.
ty::ConstKind::Unevaluated(ty::UnevaluatedConst { def, args }) => {
diff --git a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
index 60d9d6578..cb6513639 100644
--- a/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
+++ b/compiler/rustc_infer/src/infer/lexical_region_resolve/mod.rs
@@ -15,7 +15,6 @@ use rustc_data_structures::graph::implementation::{
use rustc_data_structures::intern::Interned;
use rustc_index::{IndexSlice, IndexVec};
use rustc_middle::ty::fold::TypeFoldable;
-use rustc_middle::ty::PlaceholderRegion;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_middle::ty::{ReEarlyBound, ReErased, ReError, ReFree, ReStatic};
use rustc_middle::ty::{ReLateBound, RePlaceholder, ReVar};
@@ -173,38 +172,6 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
}
}
- /// Gets the LUb of a given region and the empty region
- fn lub_empty(&self, a_region: Region<'tcx>) -> Result<Region<'tcx>, PlaceholderRegion> {
- match *a_region {
- ReLateBound(..) | ReErased => {
- bug!("cannot relate region: {:?}", a_region);
- }
-
- ReVar(v_id) => {
- span_bug!(
- self.var_infos[v_id].origin.span(),
- "lub invoked with non-concrete regions: {:?}",
- a_region,
- );
- }
-
- ReStatic => {
- // nothing lives longer than `'static`
- Ok(self.tcx().lifetimes.re_static)
- }
-
- ReError(_) => Ok(a_region),
-
- ReEarlyBound(_) | ReFree(_) => {
- // All empty regions are less than early-bound, free,
- // and scope regions.
- Ok(a_region)
- }
-
- RePlaceholder(placeholder) => Err(placeholder),
- }
- }
-
fn expansion(&self, var_values: &mut LexicalRegionResolutions<'tcx>) {
// In the first pass, we expand region vids according to constraints we
// have previously found. In the second pass, we loop through the region
@@ -247,27 +214,25 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
true
}
VarValue::Value(cur_region) => {
- let lub = match self.lub_empty(cur_region) {
- Ok(r) => r,
- // If the empty and placeholder regions are in the same universe,
- // then the LUB is the Placeholder region (which is the cur_region).
- // If they are not in the same universe, the LUB is the Static lifetime.
- Err(placeholder) if a_universe == placeholder.universe => {
- cur_region
+ match *cur_region {
+ // If this empty region is from a universe that can name the
+ // placeholder universe, then the LUB is the Placeholder region
+ // (which is the cur_region). Otherwise, the LUB is the Static
+ // lifetime.
+ RePlaceholder(placeholder)
+ if !a_universe.can_name(placeholder.universe) =>
+ {
+ let lub = self.tcx().lifetimes.re_static;
+ debug!(
+ "Expanding value of {:?} from {:?} to {:?}",
+ b_vid, cur_region, lub
+ );
+
+ *b_data = VarValue::Value(lub);
+ true
}
- Err(_) => self.tcx().lifetimes.re_static,
- };
-
- if lub == cur_region {
- false
- } else {
- debug!(
- "Expanding value of {:?} from {:?} to {:?}",
- b_vid, cur_region, lub
- );
-
- *b_data = VarValue::Value(lub);
- true
+
+ _ => false,
}
}
@@ -341,15 +306,19 @@ impl<'cx, 'tcx> LexicalResolver<'cx, 'tcx> {
match *b_data {
VarValue::Empty(empty_ui) => {
- let lub = match self.lub_empty(a_region) {
- Ok(r) => r,
- // If this empty region is from a universe that can
- // name the placeholder, then the placeholder is
- // larger; otherwise, the only ancestor is `'static`.
- Err(placeholder) if empty_ui.can_name(placeholder.universe) => {
- ty::Region::new_placeholder(self.tcx(), placeholder)
+ let lub = match *a_region {
+ RePlaceholder(placeholder) => {
+ // If this empty region is from a universe that can
+ // name the placeholder, then the placeholder is
+ // larger; otherwise, the only ancestor is `'static`.
+ if empty_ui.can_name(placeholder.universe) {
+ ty::Region::new_placeholder(self.tcx(), placeholder)
+ } else {
+ self.tcx().lifetimes.re_static
+ }
}
- Err(_) => self.tcx().lifetimes.re_static,
+
+ _ => a_region,
};
debug!("Expanding value of {:?} from empty lifetime to {:?}", b_vid, lub);
diff --git a/compiler/rustc_infer/src/infer/mod.rs b/compiler/rustc_infer/src/infer/mod.rs
index aaabf1482..aeb3177af 100644
--- a/compiler/rustc_infer/src/infer/mod.rs
+++ b/compiler/rustc_infer/src/infer/mod.rs
@@ -21,7 +21,7 @@ use rustc_data_structures::unify as ut;
use rustc_errors::{DiagnosticBuilder, ErrorGuaranteed};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_middle::infer::canonical::{Canonical, CanonicalVarValues};
-use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue};
+use rustc_middle::infer::unify_key::{ConstVarValue, ConstVariableValue, EffectVarValue};
use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind, ToType};
use rustc_middle::mir::interpret::{ErrorHandled, EvalToValTreeResult};
use rustc_middle::mir::ConstraintCategory;
@@ -33,13 +33,14 @@ use rustc_middle::ty::relate::RelateResult;
use rustc_middle::ty::visit::{TypeVisitable, TypeVisitableExt};
pub use rustc_middle::ty::IntVarValue;
use rustc_middle::ty::{self, GenericParamDefKind, InferConst, InferTy, Ty, TyCtxt};
-use rustc_middle::ty::{ConstVid, FloatVid, IntVid, TyVid};
+use rustc_middle::ty::{ConstVid, EffectVid, FloatVid, IntVid, TyVid};
use rustc_middle::ty::{GenericArg, GenericArgKind, GenericArgs, GenericArgsRef};
use rustc_span::symbol::Symbol;
use rustc_span::Span;
use std::cell::{Cell, RefCell};
use std::fmt;
+use std::marker::PhantomData;
use self::combine::CombineFields;
use self::error_reporting::TypeErrCtxt;
@@ -115,6 +116,9 @@ pub struct InferCtxtInner<'tcx> {
/// Map from floating variable to the kind of float it represents.
float_unification_storage: ut::UnificationTableStorage<ty::FloatVid>,
+ /// Map from effect variable to the effect param it represents.
+ effect_unification_storage: ut::UnificationTableStorage<ty::EffectVid<'tcx>>,
+
/// Tracks the set of region variables and the constraints between them.
///
/// This is initially `Some(_)` but when
@@ -172,6 +176,7 @@ impl<'tcx> InferCtxtInner<'tcx> {
const_unification_storage: ut::UnificationTableStorage::new(),
int_unification_storage: ut::UnificationTableStorage::new(),
float_unification_storage: ut::UnificationTableStorage::new(),
+ effect_unification_storage: ut::UnificationTableStorage::new(),
region_constraint_storage: Some(RegionConstraintStorage::new()),
region_obligations: vec![],
opaque_type_storage: Default::default(),
@@ -223,6 +228,10 @@ impl<'tcx> InferCtxtInner<'tcx> {
self.const_unification_storage.with_log(&mut self.undo_log)
}
+ fn effect_unification_table(&mut self) -> UnificationTable<'_, 'tcx, ty::EffectVid<'tcx>> {
+ self.effect_unification_storage.with_log(&mut self.undo_log)
+ }
+
#[inline]
pub fn unwrap_region_constraints(&mut self) -> RegionConstraintCollector<'_, 'tcx> {
self.region_constraint_storage
@@ -356,6 +365,7 @@ impl<'tcx> ty::InferCtxtLike<TyCtxt<'tcx>> for InferCtxt<'tcx> {
Err(universe) => Some(universe),
Ok(_) => None,
},
+ EffectVar(_) => None,
Fresh(_) => None,
}
}
@@ -373,7 +383,7 @@ pub enum ValuePairs<'tcx> {
Aliases(ExpectedFound<ty::AliasTy<'tcx>>),
TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>),
PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>),
- Sigs(ExpectedFound<ty::FnSig<'tcx>>),
+ PolySigs(ExpectedFound<ty::PolyFnSig<'tcx>>),
ExistentialTraitRef(ExpectedFound<ty::PolyExistentialTraitRef<'tcx>>),
ExistentialProjection(ExpectedFound<ty::PolyExistentialProjection<'tcx>>),
}
@@ -764,19 +774,32 @@ impl<'tcx> InferCtxt<'tcx> {
.collect();
vars.extend(
(0..inner.int_unification_table().len())
- .map(|i| ty::IntVid { index: i as u32 })
+ .map(|i| ty::IntVid::from_u32(i as u32))
.filter(|&vid| inner.int_unification_table().probe_value(vid).is_none())
.map(|v| Ty::new_int_var(self.tcx, v)),
);
vars.extend(
(0..inner.float_unification_table().len())
- .map(|i| ty::FloatVid { index: i as u32 })
+ .map(|i| ty::FloatVid::from_u32(i as u32))
.filter(|&vid| inner.float_unification_table().probe_value(vid).is_none())
.map(|v| Ty::new_float_var(self.tcx, v)),
);
vars
}
+ pub fn unsolved_effects(&self) -> Vec<ty::Const<'tcx>> {
+ let mut inner = self.inner.borrow_mut();
+ let mut table = inner.effect_unification_table();
+
+ (0..table.len())
+ .map(|i| ty::EffectVid { index: i as u32, phantom: PhantomData })
+ .filter(|&vid| table.probe_value(vid).is_none())
+ .map(|v| {
+ ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(v), self.tcx.types.bool)
+ })
+ .collect()
+ }
+
fn combine_fields<'a>(
&'a self,
trace: TypeTrace<'tcx>,
@@ -1158,7 +1181,10 @@ impl<'tcx> InferCtxt<'tcx> {
Ty::new_var(self.tcx, ty_var_id).into()
}
- GenericParamDefKind::Const { .. } => {
+ GenericParamDefKind::Const { is_host_effect, .. } => {
+ if is_host_effect {
+ return self.var_for_effect(param);
+ }
let origin = ConstVariableOrigin {
kind: ConstVariableOriginKind::ConstParameterDefinition(
param.name,
@@ -1184,6 +1210,17 @@ impl<'tcx> InferCtxt<'tcx> {
}
}
+ pub fn var_for_effect(&self, param: &ty::GenericParamDef) -> GenericArg<'tcx> {
+ let effect_vid = self.inner.borrow_mut().effect_unification_table().new_key(None);
+ let ty = self
+ .tcx
+ .type_of(param.def_id)
+ .no_bound_vars()
+ .expect("const parameter types cannot be generic");
+ debug_assert_eq!(self.tcx.types.bool, ty);
+ ty::Const::new_infer(self.tcx, ty::InferConst::EffectVar(effect_vid), ty).into()
+ }
+
/// Given a set of generics defined on a type or impl, returns a substitution mapping each
/// type/region parameter to a fresh inference variable.
pub fn fresh_args_for_item(&self, span: Span, def_id: DefId) -> GenericArgsRef<'tcx> {
@@ -1298,6 +1335,10 @@ impl<'tcx> InferCtxt<'tcx> {
self.inner.borrow_mut().const_unification_table().find(var)
}
+ pub fn root_effect_var(&self, var: ty::EffectVid<'tcx>) -> ty::EffectVid<'tcx> {
+ self.inner.borrow_mut().effect_unification_table().find(var)
+ }
+
/// Resolves an int var to a rigid int type, if it was constrained to one,
/// or else the root int var in the unification table.
pub fn opportunistic_resolve_int_var(&self, vid: ty::IntVid) -> Ty<'tcx> {
@@ -1369,6 +1410,10 @@ impl<'tcx> InferCtxt<'tcx> {
}
}
+ pub fn probe_effect_var(&self, vid: EffectVid<'tcx>) -> Option<EffectVarValue<'tcx>> {
+ self.inner.borrow_mut().effect_unification_table().probe_value(vid)
+ }
+
/// Attempts to resolve all type/region/const variables in
/// `value`. Region inference must have been run already (e.g.,
/// by calling `resolve_regions_and_report_errors`). If some
@@ -1555,9 +1600,12 @@ impl<'tcx> InferCtxt<'tcx> {
if let Some(ct) = tcx.thir_abstract_const(unevaluated.def)? {
let ct = tcx.expand_abstract_consts(ct.instantiate(tcx, args));
if let Err(e) = ct.error_reported() {
- return Err(ErrorHandled::Reported(e.into()));
+ return Err(ErrorHandled::Reported(
+ e.into(),
+ span.unwrap_or(rustc_span::DUMMY_SP),
+ ));
} else if ct.has_non_region_infer() || ct.has_non_region_param() {
- return Err(ErrorHandled::TooGeneric);
+ return Err(ErrorHandled::TooGeneric(span.unwrap_or(rustc_span::DUMMY_SP)));
} else {
args = replace_param_and_infer_args_with_placeholder(tcx, args);
}
@@ -1649,6 +1697,14 @@ impl<'tcx> InferCtxt<'tcx> {
ConstVariableValue::Known { .. } => true,
}
}
+
+ TyOrConstInferVar::Effect(v) => {
+ // If `probe_value` returns `Some`, it never equals
+ // `ty::ConstKind::Infer(ty::InferConst::Effect(v))`.
+ //
+ // Not `inlined_probe_value(v)` because this call site is colder.
+ self.probe_effect_var(v).is_some()
+ }
}
}
}
@@ -1720,6 +1776,8 @@ pub enum TyOrConstInferVar<'tcx> {
/// Equivalent to `ty::ConstKind::Infer(ty::InferConst::Var(_))`.
Const(ConstVid<'tcx>),
+ /// Equivalent to `ty::ConstKind::Infer(ty::InferConst::EffectVar(_))`.
+ Effect(EffectVid<'tcx>),
}
impl<'tcx> TyOrConstInferVar<'tcx> {
@@ -1750,6 +1808,7 @@ impl<'tcx> TyOrConstInferVar<'tcx> {
fn maybe_from_const(ct: ty::Const<'tcx>) -> Option<Self> {
match ct.kind() {
ty::ConstKind::Infer(InferConst::Var(v)) => Some(TyOrConstInferVar::Const(v)),
+ ty::ConstKind::Infer(InferConst::EffectVar(v)) => Some(TyOrConstInferVar::Effect(v)),
_ => None,
}
}
@@ -1793,17 +1852,24 @@ impl<'a, 'tcx> TypeFolder<TyCtxt<'tcx>> for ShallowResolver<'a, 'tcx> {
}
fn fold_const(&mut self, ct: ty::Const<'tcx>) -> ty::Const<'tcx> {
- if let ty::ConstKind::Infer(InferConst::Var(vid)) = ct.kind() {
- self.infcx
+ match ct.kind() {
+ ty::ConstKind::Infer(InferConst::Var(vid)) => self
+ .infcx
.inner
.borrow_mut()
.const_unification_table()
.probe_value(vid)
.val
.known()
- .unwrap_or(ct)
- } else {
- ct
+ .unwrap_or(ct),
+ ty::ConstKind::Infer(InferConst::EffectVar(vid)) => self
+ .infcx
+ .inner
+ .borrow_mut()
+ .effect_unification_table()
+ .probe_value(vid)
+ .map_or(ct, |val| val.as_const(self.infcx.tcx)),
+ _ => ct,
}
}
}
diff --git a/compiler/rustc_infer/src/infer/outlives/components.rs b/compiler/rustc_infer/src/infer/outlives/components.rs
index 2ac9568f6..6a9d40daa 100644
--- a/compiler/rustc_infer/src/infer/outlives/components.rs
+++ b/compiler/rustc_infer/src/infer/outlives/components.rs
@@ -112,7 +112,7 @@ fn compute_components<'tcx>(
}
// All regions are bound inside a witness
- ty::GeneratorWitness(..) | ty::GeneratorWitnessMIR(..) => (),
+ ty::GeneratorWitness(..) => (),
// OutlivesTypeParameterEnv -- the actual checking that `X:'a`
// is implied by the environment is done in regionck.
diff --git a/compiler/rustc_infer/src/infer/sub.rs b/compiler/rustc_infer/src/infer/sub.rs
index 27e1ed56f..0c3bb633b 100644
--- a/compiler/rustc_infer/src/infer/sub.rs
+++ b/compiler/rustc_infer/src/infer/sub.rs
@@ -147,25 +147,6 @@ impl<'tcx> TypeRelation<'tcx> for Sub<'_, '_, 'tcx> {
);
Ok(a)
}
- // Optimization of GeneratorWitness relation since we know that all
- // free regions are replaced with bound regions during construction.
- // This greatly speeds up subtyping of GeneratorWitness.
- (&ty::GeneratorWitness(a_types), &ty::GeneratorWitness(b_types)) => {
- let a_types = infcx.tcx.anonymize_bound_vars(a_types);
- let b_types = infcx.tcx.anonymize_bound_vars(b_types);
- if a_types.bound_vars() == b_types.bound_vars() {
- let (a_types, b_types) = infcx.instantiate_binder_with_placeholders(
- a_types.map_bound(|a_types| (a_types, b_types.skip_binder())),
- );
- for (a, b) in std::iter::zip(a_types, b_types) {
- self.relate(a, b)?;
- }
- Ok(a)
- } else {
- Err(ty::error::TypeError::Sorts(ty::relate::expected_found(self, a, b)))
- }
- }
-
_ => {
self.fields.infcx.super_combine_tys(self, a, b)?;
Ok(a)
diff --git a/compiler/rustc_infer/src/infer/undo_log.rs b/compiler/rustc_infer/src/infer/undo_log.rs
index 25d06b21e..79144b3e6 100644
--- a/compiler/rustc_infer/src/infer/undo_log.rs
+++ b/compiler/rustc_infer/src/infer/undo_log.rs
@@ -24,6 +24,7 @@ pub(crate) enum UndoLog<'tcx> {
ConstUnificationTable(sv::UndoLog<ut::Delegate<ty::ConstVid<'tcx>>>),
IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),
FloatUnificationTable(sv::UndoLog<ut::Delegate<ty::FloatVid>>),
+ EffectUnificationTable(sv::UndoLog<ut::Delegate<ty::EffectVid<'tcx>>>),
RegionConstraintCollector(region_constraints::UndoLog<'tcx>),
RegionUnificationTable(sv::UndoLog<ut::Delegate<RegionVidKey<'tcx>>>),
ProjectionCache(traits::UndoLog<'tcx>),
@@ -55,6 +56,7 @@ impl_from! {
IntUnificationTable(sv::UndoLog<ut::Delegate<ty::IntVid>>),
FloatUnificationTable(sv::UndoLog<ut::Delegate<ty::FloatVid>>),
+ EffectUnificationTable(sv::UndoLog<ut::Delegate<ty::EffectVid<'tcx>>>),
ConstUnificationTable(sv::UndoLog<ut::Delegate<ty::ConstVid<'tcx>>>),
@@ -71,6 +73,7 @@ impl<'tcx> Rollback<UndoLog<'tcx>> for InferCtxtInner<'tcx> {
UndoLog::ConstUnificationTable(undo) => self.const_unification_storage.reverse(undo),
UndoLog::IntUnificationTable(undo) => self.int_unification_storage.reverse(undo),
UndoLog::FloatUnificationTable(undo) => self.float_unification_storage.reverse(undo),
+ UndoLog::EffectUnificationTable(undo) => self.effect_unification_storage.reverse(undo),
UndoLog::RegionConstraintCollector(undo) => {
self.region_constraint_storage.as_mut().unwrap().reverse(undo)
}