Rollup merge of #60742 - varkor:fn-const-array-parameter, r=eddyb

Allow const parameters in array sizes to be unified

Fixes https://github.com/rust-lang/rust/issues/60632.
Fixes https://github.com/rust-lang/rust/issues/60744.
Fixes https://github.com/rust-lang/rust/pull/60923.
(The last commit should probably be viewed in isolation, as it just renames things from `type` to `kind`.)

r? @eddyb
This commit is contained in:
Mazdak Farrokhzad 2019-05-29 00:19:52 +02:00 committed by GitHub
commit d85e256a87
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
66 changed files with 396 additions and 199 deletions

View file

@ -652,7 +652,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
for sp in prior_arms {
err.span_label(*sp, format!(
"this is found to be of type `{}`",
self.resolve_type_vars_if_possible(&last_ty),
self.resolve_vars_if_possible(&last_ty),
));
}
} else if let Some(sp) = prior_arms.last() {
@ -1278,7 +1278,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
&self,
exp_found: &ty::error::ExpectedFound<Ty<'tcx>>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> {
let exp_found = self.resolve_type_vars_if_possible(exp_found);
let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() {
return None;
}
@ -1291,7 +1291,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
&self,
exp_found: &ty::error::ExpectedFound<T>,
) -> Option<(DiagnosticStyledString, DiagnosticStyledString)> {
let exp_found = self.resolve_type_vars_if_possible(exp_found);
let exp_found = self.resolve_vars_if_possible(exp_found);
if exp_found.references_error() {
return None;
}

View file

@ -24,7 +24,7 @@ impl<'a, 'gcx, 'tcx> FindLocalByTypeVisitor<'a, 'gcx, 'tcx> {
});
match ty_opt {
Some(ty) => {
let ty = self.infcx.resolve_type_vars_if_possible(&ty);
let ty = self.infcx.resolve_vars_if_possible(&ty);
ty.walk().any(|inner_ty| {
inner_ty == self.target_ty || match (&inner_ty.sty, &self.target_ty.sty) {
(&Infer(TyVar(a_vid)), &Infer(TyVar(b_vid))) => {
@ -94,7 +94,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span: Span,
ty: Ty<'tcx>
) -> DiagnosticBuilder<'gcx> {
let ty = self.resolve_type_vars_if_possible(&ty);
let ty = self.resolve_vars_if_possible(&ty);
let name = self.extract_type_name(&ty, None);
let mut err_span = span;
@ -166,7 +166,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
span: Span,
ty: Ty<'tcx>
) -> DiagnosticBuilder<'gcx> {
let ty = self.resolve_type_vars_if_possible(&ty);
let ty = self.resolve_vars_if_possible(&ty);
let name = self.extract_type_name(&ty, None);
let mut err = struct_span_err!(self.tcx.sess,

View file

@ -210,11 +210,11 @@ impl NiceRegionError<'me, 'gcx, 'tcx> {
_ => (),
}
let expected_trait_ref = self.infcx.resolve_type_vars_if_possible(&ty::TraitRef {
let expected_trait_ref = self.infcx.resolve_vars_if_possible(&ty::TraitRef {
def_id: trait_def_id,
substs: expected_substs,
});
let actual_trait_ref = self.infcx.resolve_type_vars_if_possible(&ty::TraitRef {
let actual_trait_ref = self.infcx.resolve_vars_if_possible(&ty::TraitRef {
def_id: trait_def_id,
substs: actual_substs,
});

View file

@ -74,7 +74,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let (mut fudger, value) = self.probe(|snapshot| {
match f() {
Ok(value) => {
let value = self.resolve_type_vars_if_possible(&value);
let value = self.resolve_vars_if_possible(&value);
// At this point, `value` could in principle refer
// to inference variables that have been created during

View file

@ -1174,7 +1174,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// Process the region constraints and report any errors that
/// result. After this, no more unification operations should be
/// done -- or the compiler will panic -- but it is legal to use
/// `resolve_type_vars_if_possible` as well as `fully_resolve`.
/// `resolve_vars_if_possible` as well as `fully_resolve`.
pub fn resolve_regions_and_report_errors(
&self,
region_context: DefId,
@ -1262,7 +1262,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
pub fn ty_to_string(&self, t: Ty<'tcx>) -> String {
self.resolve_type_vars_if_possible(&t).to_string()
self.resolve_vars_if_possible(&t).to_string()
}
pub fn tys_to_string(&self, ts: &[Ty<'tcx>]) -> String {
@ -1271,7 +1271,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
pub fn trait_ref_to_string(&self, t: &ty::TraitRef<'tcx>) -> String {
self.resolve_type_vars_if_possible(t).to_string()
self.resolve_vars_if_possible(t).to_string()
}
/// If `TyVar(vid)` resolves to a type, return that type. Else, return the
@ -1297,20 +1297,20 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
self.type_variables.borrow_mut().root_var(var)
}
/// Where possible, replaces type/int/float variables in
/// Where possible, replaces type/const variables in
/// `value` with their final value. Note that region variables
/// are unaffected. If a type variable has not been unified, it
/// are unaffected. If a type/const variable has not been unified, it
/// is left as is. This is an idempotent operation that does
/// not affect inference state in any way and so you can do it
/// at will.
pub fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
pub fn resolve_vars_if_possible<T>(&self, value: &T) -> T
where
T: TypeFoldable<'tcx>,
{
if !value.needs_infer() {
return value.clone(); // avoid duplicated subst-folding
}
let mut r = resolve::OpportunisticTypeResolver::new(self);
let mut r = resolve::OpportunisticVarResolver::new(self);
value.fold_with(&mut r)
}
@ -1318,7 +1318,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// process of visiting `T`, this will resolve (where possible)
/// type variables in `T`, but it never constructs the final,
/// resolved type, so it's more efficient than
/// `resolve_type_vars_if_possible()`.
/// `resolve_vars_if_possible()`.
pub fn unresolved_type_vars<T>(&self, value: &T) -> Option<(Ty<'tcx>, Option<Span>)>
where
T: TypeFoldable<'tcx>,
@ -1389,7 +1389,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
where
M: FnOnce(String) -> DiagnosticBuilder<'tcx>,
{
let actual_ty = self.resolve_type_vars_if_possible(&actual_ty);
let actual_ty = self.resolve_vars_if_possible(&actual_ty);
debug!("type_error_struct_with_diag({:?}, {:?})", sp, actual_ty);
// Don't report an error if actual type is `Error`.
@ -1446,7 +1446,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
ty: Ty<'tcx>,
span: Span,
) -> bool {
let ty = self.resolve_type_vars_if_possible(&ty);
let ty = self.resolve_vars_if_possible(&ty);
// Even if the type may have no inference variables, during
// type-checking closure types are in local tables only.

View file

@ -286,7 +286,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
let tcx = self.tcx;
let concrete_ty = self.resolve_type_vars_if_possible(&opaque_defn.concrete_ty);
let concrete_ty = self.resolve_vars_if_possible(&opaque_defn.concrete_ty);
debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty);

View file

@ -168,7 +168,7 @@ impl<'a, 'gcx: 'tcx, 'tcx: 'a> OutlivesEnvironment<'tcx> {
debug!("add_implied_bounds()");
for &ty in fn_sig_tys {
let ty = infcx.resolve_type_vars_if_possible(&ty);
let ty = infcx.resolve_vars_if_possible(&ty);
debug!("add_implied_bounds: ty = {}", ty);
let implied_bounds = infcx.implied_outlives_bounds(self.param_env, body_id, ty, span);
self.add_outlives_bounds(Some(infcx), implied_bounds)

View file

@ -177,7 +177,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
sup_type, sub_region, origin
);
let sup_type = self.resolve_type_vars_if_possible(&sup_type);
let sup_type = self.resolve_vars_if_possible(&sup_type);
if let Some(region_bound_pairs) = region_bound_pairs_map.get(&body_id) {
let outlives = &mut TypeOutlives::new(
@ -215,7 +215,7 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> {
implicit_region_bound,
param_env,
);
let ty = self.resolve_type_vars_if_possible(&ty);
let ty = self.resolve_vars_if_possible(&ty);
outlives.type_must_outlive(origin, ty, region);
}
}

View file

@ -1,28 +1,28 @@
use super::{InferCtxt, FixupError, FixupResult, Span, type_variable::TypeVariableOrigin};
use crate::mir::interpret::ConstValue;
use crate::ty::{self, Ty, TyCtxt, TypeFoldable, InferConst};
use crate::ty::{self, Ty, Const, TyCtxt, TypeFoldable, InferConst, TypeFlags};
use crate::ty::fold::{TypeFolder, TypeVisitor};
///////////////////////////////////////////////////////////////////////////
// OPPORTUNISTIC TYPE RESOLVER
// OPPORTUNISTIC VAR RESOLVER
/// The opportunistic type resolver can be used at any time. It simply replaces
/// type variables that have been unified with the things they have
/// The opportunistic resolver can be used at any time. It simply replaces
/// type/const variables that have been unified with the things they have
/// been unified with (similar to `shallow_resolve`, but deep). This is
/// useful for printing messages etc but also required at various
/// points for correctness.
pub struct OpportunisticTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
pub struct OpportunisticVarResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> {
infcx: &'a InferCtxt<'a, 'gcx, 'tcx>,
}
impl<'a, 'gcx, 'tcx> OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> OpportunisticVarResolver<'a, 'gcx, 'tcx> {
#[inline]
pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self {
OpportunisticTypeResolver { infcx }
OpportunisticVarResolver { infcx }
}
}
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'gcx, 'tcx> {
impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticVarResolver<'a, 'gcx, 'tcx> {
fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> {
self.infcx.tcx
}
@ -31,8 +31,17 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'g
if !t.has_infer_types() {
t // micro-optimize -- if there is nothing in this type that this fold affects...
} else {
let t0 = self.infcx.shallow_resolve(t);
t0.super_fold_with(self)
let t = self.infcx.shallow_resolve(t);
t.super_fold_with(self)
}
}
fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> {
if !ct.has_type_flags(TypeFlags::HAS_CT_INFER) {
ct // micro-optimize -- if there is nothing in this const that this fold affects...
} else {
let ct = self.infcx.shallow_resolve(ct);
ct.super_fold_with(self)
}
}
}

View file

@ -458,10 +458,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
.unwrap_or(true)
}
fn resolve_type_vars_if_possible<T>(&self, value: &T) -> T
fn resolve_vars_if_possible<T>(&self, value: &T) -> T
where T: TypeFoldable<'tcx>
{
self.infcx.map(|infcx| infcx.resolve_type_vars_if_possible(value))
self.infcx.map(|infcx| infcx.resolve_vars_if_possible(value))
.unwrap_or_else(|| value.clone())
}
@ -475,7 +475,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
-> McResult<Ty<'tcx>> {
match ty {
Some(ty) => {
let ty = self.resolve_type_vars_if_possible(&ty);
let ty = self.resolve_vars_if_possible(&ty);
if ty.references_error() || ty.is_ty_var() {
debug!("resolve_type_vars_or_error: error from {:?}", ty);
Err(())
@ -602,7 +602,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> {
where F: FnOnce() -> McResult<cmt_<'tcx>>
{
debug!("cat_expr_adjusted_with({:?}): {:?}", adjustment, expr);
let target = self.resolve_type_vars_if_possible(&adjustment.target);
let target = self.resolve_vars_if_possible(&adjustment.target);
match adjustment.kind {
adjustment::Adjust::Deref(overloaded) => {
// Equivalent to *expr or something similar.

View file

@ -307,9 +307,9 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
continue;
}
// Call infcx.resolve_type_vars_if_possible to see if we can
// Call infcx.resolve_vars_if_possible to see if we can
// get rid of any inference variables.
let obligation = infcx.resolve_type_vars_if_possible(
let obligation = infcx.resolve_vars_if_possible(
&Obligation::new(dummy_cause.clone(), new_env, pred)
);
let result = select.select(&obligation);
@ -642,7 +642,7 @@ impl<'a, 'tcx> AutoTraitFinder<'a, 'tcx> {
fresh_preds.insert(self.clean_pred(select.infcx(), predicate));
// Resolve any inference variables that we can, to help selection succeed
predicate = select.infcx().resolve_type_vars_if_possible(&predicate);
predicate = select.infcx().resolve_vars_if_possible(&predicate);
// We only add a predicate as a user-displayable bound if
// it involves a generic parameter, and doesn't contain

View file

@ -33,7 +33,7 @@ fn in_environment(
obligation: PredicateObligation<'tcx>
) -> InEnvironment<'tcx, PredicateObligation<'tcx>> {
assert!(!infcx.is_in_snapshot());
let obligation = infcx.resolve_type_vars_if_possible(&obligation);
let obligation = infcx.resolve_vars_if_possible(&obligation);
let environment = match obligation.param_env.def_id {
Some(def_id) => infcx.tcx.environment(def_id),

View file

@ -153,11 +153,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
bug!("Encountered errors `{:?}` resolving bounds after type-checking", errors);
}
let result = self.resolve_type_vars_if_possible(result);
let result = self.resolve_vars_if_possible(result);
let result = self.tcx.erase_regions(&result);
self.tcx.lift_to_global(&result).unwrap_or_else(||
bug!("Uninferred types/regions in `{:?}`", result)
bug!("Uninferred types/regions/consts in `{:?}`", result)
)
}
}

View file

@ -155,7 +155,7 @@ fn overlap_within_probe(
a_impl_header.predicates
.iter()
.chain(&b_impl_header.predicates)
.map(|p| infcx.resolve_type_vars_if_possible(p))
.map(|p| infcx.resolve_vars_if_possible(p))
.map(|p| Obligation { cause: ObligationCause::dummy(),
param_env,
recursion_depth: 0,
@ -171,7 +171,7 @@ fn overlap_within_probe(
return None
}
let impl_header = selcx.infcx().resolve_type_vars_if_possible(&a_impl_header);
let impl_header = selcx.infcx().resolve_vars_if_possible(&a_impl_header);
let intercrate_ambiguity_causes = selcx.take_intercrate_ambiguity_causes();
debug!("overlap: intercrate_ambiguity_causes={:#?}", intercrate_ambiguity_causes);

View file

@ -186,7 +186,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
error: &MismatchedProjectionTypes<'tcx>)
{
let predicate =
self.resolve_type_vars_if_possible(&obligation.predicate);
self.resolve_vars_if_possible(&obligation.predicate);
if predicate.references_error() {
return
@ -531,7 +531,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
where T: fmt::Display + TypeFoldable<'tcx>
{
let predicate =
self.resolve_type_vars_if_possible(&obligation.predicate);
self.resolve_vars_if_possible(&obligation.predicate);
let mut err = struct_span_err!(self.tcx.sess, obligation.cause.span, E0275,
"overflow evaluating the requirement `{}`",
predicate);
@ -553,7 +553,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
/// we do not suggest increasing the overflow limit, which is not
/// going to help).
pub fn report_overflow_error_cycle(&self, cycle: &[PredicateObligation<'tcx>]) -> ! {
let cycle = self.resolve_type_vars_if_possible(&cycle.to_owned());
let cycle = self.resolve_vars_if_possible(&cycle.to_owned());
assert!(cycle.len() > 0);
debug!("report_overflow_error_cycle: cycle={:?}", cycle);
@ -589,7 +589,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
fn get_parent_trait_ref(&self, code: &ObligationCauseCode<'tcx>) -> Option<String> {
match code {
&ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
let parent_trait_ref = self.resolve_type_vars_if_possible(
let parent_trait_ref = self.resolve_vars_if_possible(
&data.parent_trait_ref);
match self.get_parent_trait_ref(&data.parent_code) {
Some(t) => Some(t),
@ -625,7 +625,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
match obligation.predicate {
ty::Predicate::Trait(ref trait_predicate) => {
let trait_predicate =
self.resolve_type_vars_if_possible(trait_predicate);
self.resolve_vars_if_possible(trait_predicate);
if self.tcx.sess.has_errors() && trait_predicate.references_error() {
return;
@ -749,7 +749,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
ty::Predicate::RegionOutlives(ref predicate) => {
let predicate = self.resolve_type_vars_if_possible(predicate);
let predicate = self.resolve_vars_if_possible(predicate);
let err = self.region_outlives_predicate(&obligation.cause,
&predicate).err().unwrap();
struct_span_err!(
@ -761,7 +761,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
ty::Predicate::Projection(..) | ty::Predicate::TypeOutlives(..) => {
let predicate =
self.resolve_type_vars_if_possible(&obligation.predicate);
self.resolve_vars_if_possible(&obligation.predicate);
struct_span_err!(self.tcx.sess, span, E0280,
"the requirement `{}` is not satisfied",
predicate)
@ -852,8 +852,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
OutputTypeParameterMismatch(ref found_trait_ref, ref expected_trait_ref, _) => {
let found_trait_ref = self.resolve_type_vars_if_possible(&*found_trait_ref);
let expected_trait_ref = self.resolve_type_vars_if_possible(&*expected_trait_ref);
let found_trait_ref = self.resolve_vars_if_possible(&*found_trait_ref);
let expected_trait_ref = self.resolve_vars_if_possible(&*expected_trait_ref);
if expected_trait_ref.self_ty().references_error() {
return;
@ -1345,7 +1345,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
// ambiguous impls. The latter *ought* to be a
// coherence violation, so we don't report it here.
let predicate = self.resolve_type_vars_if_possible(&obligation.predicate);
let predicate = self.resolve_vars_if_possible(&obligation.predicate);
let span = obligation.cause.span;
debug!("maybe_report_ambiguity(predicate={:?}, obligation={:?})",
@ -1617,7 +1617,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
err.note("shared static variables must have a type that implements `Sync`");
}
ObligationCauseCode::BuiltinDerivedObligation(ref data) => {
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
let ty = parent_trait_ref.skip_binder().self_ty();
err.note(&format!("required because it appears within the type `{}`", ty));
obligated_types.push(ty);
@ -1631,7 +1631,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
}
}
ObligationCauseCode::ImplDerivedObligation(ref data) => {
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
err.note(
&format!("required because of the requirements on the impl of `{}` for `{}`",
parent_trait_ref,
@ -1672,7 +1672,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
obligated_types: &mut Vec<&ty::TyS<'tcx>>,
cause_code: &ObligationCauseCode<'tcx>) -> bool {
if let ObligationCauseCode::BuiltinDerivedObligation(ref data) = cause_code {
let parent_trait_ref = self.resolve_type_vars_if_possible(&data.parent_trait_ref);
let parent_trait_ref = self.resolve_vars_if_possible(&data.parent_trait_ref);
if obligated_types.iter().any(|ot| ot == &parent_trait_ref.skip_binder().self_ty()) {
return true;

View file

@ -178,7 +178,7 @@ impl<'tcx> TraitEngine<'tcx> for FulfillmentContext<'tcx> {
{
// this helps to reduce duplicate errors, as well as making
// debug output much nicer to read and so on.
let obligation = infcx.resolve_type_vars_if_possible(&obligation);
let obligation = infcx.resolve_vars_if_possible(&obligation);
debug!("register_predicate_obligation(obligation={:?})", obligation);
@ -261,7 +261,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
}) {
debug!("process_predicate: pending obligation {:?} still stalled on {:?}",
self.selcx.infcx()
.resolve_type_vars_if_possible(&pending_obligation.obligation),
.resolve_vars_if_possible(&pending_obligation.obligation),
pending_obligation.stalled_on);
return ProcessResult::Unchanged;
}
@ -272,7 +272,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
if obligation.predicate.has_infer_types() {
obligation.predicate =
self.selcx.infcx().resolve_type_vars_if_possible(&obligation.predicate);
self.selcx.infcx().resolve_vars_if_possible(&obligation.predicate);
}
debug!("process_obligation: obligation = {:?}", obligation);
@ -318,7 +318,7 @@ impl<'a, 'b, 'gcx, 'tcx> ObligationProcessor for FulfillProcessor<'a, 'b, 'gcx,
trait_ref_type_vars(self.selcx, data.to_poly_trait_ref());
debug!("process_predicate: pending obligation {:?} now stalled on {:?}",
self.selcx.infcx().resolve_type_vars_if_possible(obligation),
self.selcx.infcx().resolve_vars_if_possible(obligation),
pending_obligation.stalled_on);
ProcessResult::Unchanged
@ -519,7 +519,7 @@ fn trait_ref_type_vars<'a, 'gcx, 'tcx>(selcx: &mut SelectionContext<'a, 'gcx, 't
{
t.skip_binder() // ok b/c this check doesn't care about regions
.input_types()
.map(|t| selcx.infcx().resolve_type_vars_if_possible(&t))
.map(|t| selcx.infcx().resolve_vars_if_possible(&t))
.filter(|t| t.has_infer_types())
.flat_map(|t| t.walk())
.filter(|t| match t.sty { ty::Infer(_) => true, _ => false })

View file

@ -927,7 +927,7 @@ pub fn fully_normalize<'a, 'gcx, 'tcx, T>(
debug!("fully_normalize: select_all_or_error start");
fulfill_cx.select_all_or_error(infcx)?;
debug!("fully_normalize: select_all_or_error complete");
let resolved_value = infcx.resolve_type_vars_if_possible(&normalized_value);
let resolved_value = infcx.resolve_vars_if_possible(&normalized_value);
debug!("fully_normalize: resolved_value={:?}", resolved_value);
Ok(resolved_value)
}

View file

@ -312,7 +312,7 @@ impl<'a, 'b, 'gcx, 'tcx> AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx> {
}
fn fold<T:TypeFoldable<'tcx>>(&mut self, value: &T) -> T {
let value = self.selcx.infcx().resolve_type_vars_if_possible(value);
let value = self.selcx.infcx().resolve_vars_if_possible(value);
if !value.has_projections() {
value
@ -508,7 +508,7 @@ fn opt_normalize_projection_type<'a, 'b, 'gcx, 'tcx>(
{
let infcx = selcx.infcx();
let projection_ty = infcx.resolve_type_vars_if_possible(&projection_ty);
let projection_ty = infcx.resolve_vars_if_possible(&projection_ty);
let cache_key = ProjectionCacheKey { ty: projection_ty };
debug!("opt_normalize_projection_type(\
@ -1614,7 +1614,7 @@ impl<'cx, 'gcx, 'tcx> ProjectionCacheKey<'tcx> {
// from a specific call to `opt_normalize_projection_type` - if
// there's no precise match, the original cache entry is "stranded"
// anyway.
ty: infcx.resolve_type_vars_if_possible(&predicate.projection_ty)
ty: infcx.resolve_vars_if_possible(&predicate.projection_ty)
})
}
}

View file

@ -54,7 +54,7 @@ impl<'cx, 'gcx, 'tcx> At<'cx, 'gcx, 'tcx> {
&orig_values,
result)
{
let ty = self.infcx.resolve_type_vars_if_possible(&ty);
let ty = self.infcx.resolve_vars_if_possible(&ty);
let kinds = value.into_kinds_reporting_overflows(tcx, span, ty);
return InferOk {
value: kinds,

View file

@ -97,7 +97,7 @@ fn scrape_region_constraints<'gcx, 'tcx, R>(
region_obligations
.iter()
.map(|(_, r_o)| (r_o.sup_type, r_o.sub_region))
.map(|(ty, r)| (infcx.resolve_type_vars_if_possible(&ty), r)),
.map(|(ty, r)| (infcx.resolve_vars_if_possible(&ty), r)),
&region_constraint_data,
);

View file

@ -1463,7 +1463,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
let obligation = &stack.obligation;
let predicate = self.infcx()
.resolve_type_vars_if_possible(&obligation.predicate);
.resolve_vars_if_possible(&obligation.predicate);
// OK to skip binder because of the nature of the
// trait-ref-is-knowable check, which does not care about
@ -1621,7 +1621,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
cause: obligation.cause.clone(),
recursion_depth: obligation.recursion_depth,
predicate: self.infcx()
.resolve_type_vars_if_possible(&obligation.predicate),
.resolve_vars_if_possible(&obligation.predicate),
};
if obligation.predicate.skip_binder().self_ty().is_ty_var() {
@ -1737,7 +1737,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> {
snapshot: &CombinedSnapshot<'_, 'tcx>,
) -> bool {
let poly_trait_predicate = self.infcx()
.resolve_type_vars_if_possible(&obligation.predicate);
.resolve_vars_if_possible(&obligation.predicate);
let (placeholder_trait_predicate, placeholder_map) = self.infcx()
.replace_bound_vars_with_placeholders(&poly_trait_predicate);
debug!(

View file

@ -278,7 +278,7 @@ fn fulfill_implication<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
// Now resolve the *substitution* we built for the target earlier, replacing
// the inference variables inside with whatever we got from fulfillment.
Ok(infcx.resolve_type_vars_if_possible(&target_substs))
Ok(infcx.resolve_vars_if_possible(&target_substs))
}
}
})

View file

@ -80,6 +80,12 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
}
};
macro_rules! pluralise {
($x:expr) => {
if $x != 1 { "s" } else { "" }
};
}
match *self {
CyclicTy(_) => write!(f, "cyclic type of infinite size"),
Mismatch => write!(f, "types differ"),
@ -94,17 +100,21 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
values.found)
}
Mutability => write!(f, "types differ in mutability"),
FixedArraySize(values) => {
write!(f, "expected an array with a fixed size of {} elements, \
found one with {} elements",
values.expected,
values.found)
}
TupleSize(values) => {
write!(f, "expected a tuple with {} elements, \
found one with {} elements",
write!(f, "expected a tuple with {} element{}, \
found one with {} element{}",
values.expected,
values.found)
pluralise!(values.expected),
values.found,
pluralise!(values.found))
}
FixedArraySize(values) => {
write!(f, "expected an array with a fixed size of {} element{}, \
found one with {} element{}",
values.expected,
pluralise!(values.expected),
values.found,
pluralise!(values.found))
}
ArgCount => {
write!(f, "incorrect number of function parameters")
@ -157,8 +167,9 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
tcx.def_path_str(values.found))
}),
ProjectionBoundsLength(ref values) => {
write!(f, "expected {} associated type bindings, found {}",
write!(f, "expected {} associated type binding{}, found {}",
values.expected,
pluralise!(values.expected),
values.found)
},
ExistentialMismatch(ref values) => {
@ -166,7 +177,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> {
&format!("trait `{}`", values.found))
}
ConstMismatch(ref values) => {
write!(f, "expected `{:?}`, found `{:?}`", values.expected, values.found)
write!(f, "expected `{}`, found `{}`", values.expected, values.found)
}
}
}

View file

@ -8,9 +8,7 @@ use crate::hir::def_id::DefId;
use crate::ty::subst::{Kind, UnpackedKind, SubstsRef};
use crate::ty::{self, Ty, TyCtxt, TypeFoldable};
use crate::ty::error::{ExpectedFound, TypeError};
use crate::mir::interpret::{GlobalId, ConstValue, Scalar};
use crate::util::common::ErrorReported;
use syntax_pos::DUMMY_SP;
use crate::mir::interpret::{ConstValue, Scalar, GlobalId};
use std::rc::Rc;
use std::iter;
use rustc_target::spec::abi;
@ -474,55 +472,19 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R,
(&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) =>
{
let t = relation.relate(&a_t, &b_t)?;
let to_u64 = |x: ty::Const<'tcx>| -> Result<u64, ErrorReported> {
match x.val {
// FIXME(const_generics): this doesn't work right now,
// because it tries to relate an `Infer` to a `Param`.
ConstValue::Unevaluated(def_id, substs) => {
// FIXME(eddyb) get the right param_env.
let param_env = ty::ParamEnv::empty();
if let Some(substs) = tcx.lift_to_global(&substs) {
let instance = ty::Instance::resolve(
tcx.global_tcx(),
param_env,
def_id,
substs,
);
if let Some(instance) = instance {
let cid = GlobalId {
instance,
promoted: None,
};
if let Some(s) = tcx.const_eval(param_env.and(cid))
.ok()
.map(|c| c.unwrap_usize(tcx)) {
return Ok(s)
}
}
match relation.relate(&sz_a, &sz_b) {
Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))),
Err(err) => {
// Check whether the lengths are both concrete/known values,
// but are unequal, for better diagnostics.
match (sz_a.assert_usize(tcx), sz_b.assert_usize(tcx)) {
(Some(sz_a_val), Some(sz_b_val)) => {
Err(TypeError::FixedArraySize(
expected_found(relation, &sz_a_val, &sz_b_val)
))
}
tcx.sess.delay_span_bug(tcx.def_span(def_id),
"array length could not be evaluated");
Err(ErrorReported)
_ => return Err(err),
}
_ => x.assert_usize(tcx).ok_or_else(|| {
tcx.sess.delay_span_bug(DUMMY_SP,
"array length could not be evaluated");
ErrorReported
})
}
};
match (to_u64(*sz_a), to_u64(*sz_b)) {
(Ok(sz_a_u64), Ok(sz_b_u64)) => {
if sz_a_u64 == sz_b_u64 {
Ok(tcx.mk_ty(ty::Array(t, sz_a)))
} else {
Err(TypeError::FixedArraySize(
expected_found(relation, &sz_a_u64, &sz_b_u64)))
}
}
// We reported an error or will ICE, so we can return Error.
(Err(ErrorReported), _) | (_, Err(ErrorReported)) => {
Ok(tcx.types.err)
}
}
}
@ -598,11 +560,36 @@ where
{
let tcx = relation.tcx();
let eagerly_eval = |x: &'tcx ty::Const<'tcx>| {
if let ConstValue::Unevaluated(def_id, substs) = x.val {
// FIXME(eddyb) get the right param_env.
let param_env = ty::ParamEnv::empty();
if let Some(substs) = tcx.lift_to_global(&substs) {
let instance = ty::Instance::resolve(
tcx.global_tcx(),
param_env,
def_id,
substs,
);
if let Some(instance) = instance {
let cid = GlobalId {
instance,
promoted: None,
};
if let Ok(ct) = tcx.const_eval(param_env.and(cid)) {
return ct.val;
}
}
}
}
x.val
};
// Currently, the values that can be unified are those that
// implement both `PartialEq` and `Eq`, corresponding to
// `structural_match` types.
// FIXME(const_generics): check for `structural_match` synthetic attribute.
match (a.val, b.val) {
match (eagerly_eval(a), eagerly_eval(b)) {
(ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => {
// The caller should handle these cases!
bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b)
@ -613,8 +600,13 @@ where
(ConstValue::Placeholder(p1), ConstValue::Placeholder(p2)) if p1 == p2 => {
Ok(a)
}
(ConstValue::Scalar(Scalar::Raw { .. }), _) if a == b => {
Ok(a)
(a_val @ ConstValue::Scalar(Scalar::Raw { .. }), b_val @ _)
if a.ty == b.ty && a_val == b_val =>
{
Ok(tcx.mk_const(ty::Const {
val: a_val,
ty: a.ty,
}))
}
(ConstValue::ByRef(..), _) => {
bug!(
@ -635,9 +627,7 @@ where
}))
}
_ => {
Err(TypeError::ConstMismatch(expected_found(relation, &a, &b)))
}
_ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))),
}
}

View file

@ -1263,7 +1263,7 @@ impl<'a, 'gcx, 'tcx> TypeChecker<'a, 'gcx, 'tcx> {
debug!(
"eq_opaque_type_and_type: concrete_ty={:?}={:?} opaque_defn_ty={:?}",
opaque_decl.concrete_ty,
infcx.resolve_type_vars_if_possible(&opaque_decl.concrete_ty),
infcx.resolve_vars_if_possible(&opaque_decl.concrete_ty),
opaque_defn_ty
);
obligations.add(infcx

View file

@ -411,7 +411,7 @@ impl context::UnificationOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
}
fn debug_ex_clause(&mut self, value: &'v ChalkExClause<'tcx>) -> Box<dyn Debug + 'v> {
let string = format!("{:?}", self.infcx.resolve_type_vars_if_possible(value));
let string = format!("{:?}", self.infcx.resolve_vars_if_possible(value));
Box::new(string)
}

View file

@ -57,7 +57,7 @@ impl ChalkInferenceContext<'cx, 'gcx, 'tcx> {
use rustc::traits::WhereClause::*;
use rustc::infer::canonical::OriginalQueryValues;
let goal = self.infcx.resolve_type_vars_if_possible(goal);
let goal = self.infcx.resolve_vars_if_possible(goal);
debug!("program_clauses(goal = {:?})", goal);

View file

@ -111,8 +111,8 @@ impl context::ResolventOps<ChalkArenas<'gcx>, ChalkArenas<'tcx>>
) -> Fallible<ChalkExClause<'tcx>> {
debug!(
"apply_answer_subst(ex_clause = {:?}, selected_goal = {:?})",
self.infcx.resolve_type_vars_if_possible(&ex_clause),
self.infcx.resolve_type_vars_if_possible(selected_goal)
self.infcx.resolve_vars_if_possible(&ex_clause),
self.infcx.resolve_vars_if_possible(selected_goal)
);
let (answer_subst, _) = self.infcx.instantiate_canonical_with_fresh_inference_vars(

View file

@ -121,7 +121,7 @@ fn compute_implied_outlives_bounds<'tcx>(
ty::Predicate::TypeOutlives(ref data) => match data.no_bound_vars() {
None => vec![],
Some(ty::OutlivesPredicate(ty_a, r_b)) => {
let ty_a = infcx.resolve_type_vars_if_possible(&ty_a);
let ty_a = infcx.resolve_vars_if_possible(&ty_a);
let mut components = smallvec![];
tcx.push_outlives_components(ty_a, &mut components);
implied_bounds_from_components(r_b, components)

View file

@ -36,7 +36,7 @@ fn normalize_ty_after_erasing_regions<'tcx>(
None,
);
let normalized_value = infcx.resolve_type_vars_if_possible(&normalized_value);
let normalized_value = infcx.resolve_vars_if_possible(&normalized_value);
let normalized_value = infcx.tcx.erase_regions(&normalized_value);
tcx.lift_to_global(&normalized_value).unwrap()
}

View file

@ -226,7 +226,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Now that we know the types can be unified we find the unified type and use
// it to type the entire expression.
let common_type = self.resolve_type_vars_if_possible(&lhs_ty);
let common_type = self.resolve_vars_if_possible(&lhs_ty);
// subtyping doesn't matter here, as the value is some kind of scalar
self.demand_eqtype_pat(pat.span, expected, lhs_ty, discrim_span);

View file

@ -98,7 +98,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
body_id,
param_env,
steps: vec![],
cur_ty: infcx.resolve_type_vars_if_possible(&base_ty),
cur_ty: infcx.resolve_vars_if_possible(&base_ty),
obligations: vec![],
at_start: true,
include_raw_pointers: false,
@ -152,7 +152,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
ty, normalized_ty, obligations);
self.obligations.extend(obligations);
Some(self.infcx.resolve_type_vars_if_possible(&normalized_ty))
Some(self.infcx.resolve_vars_if_possible(&normalized_ty))
}
/// Returns the final type, generating an error if it is an
@ -164,7 +164,7 @@ impl<'a, 'gcx, 'tcx> Autoderef<'a, 'gcx, 'tcx> {
/// Returns the final type we ended up with, which may well be an
/// inference variable (we will resolve it first, if possible).
pub fn maybe_ambiguous_final_ty(&self) -> Ty<'tcx> {
self.infcx.resolve_type_vars_if_possible(&self.cur_ty)
self.infcx.resolve_vars_if_possible(&self.cur_ty)
}
pub fn step_count(&self) -> usize {

View file

@ -82,7 +82,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
{
debug!("pointer_kind({:?}, {:?})", t, span);
let t = self.resolve_type_vars_if_possible(&t);
let t = self.resolve_vars_if_possible(&t);
if t.references_error() {
return Err(ErrorReported);
@ -334,7 +334,7 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
let tstr = fcx.ty_to_string(self.cast_ty);
let mut err = type_error_struct!(fcx.tcx.sess, self.span, self.expr_ty, E0620,
"cast to unsized type: `{}` as `{}`",
fcx.resolve_type_vars_if_possible(&self.expr_ty),
fcx.resolve_vars_if_possible(&self.expr_ty),
tstr);
match self.expr_ty.sty {
ty::Ref(_, _, mt) => {

View file

@ -282,7 +282,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
let input_tys = if is_fn {
let arg_param_ty = trait_ref.skip_binder().substs.type_at(1);
let arg_param_ty = self.resolve_type_vars_if_possible(&arg_param_ty);
let arg_param_ty = self.resolve_vars_if_possible(&arg_param_ty);
debug!("deduce_sig_from_projection: arg_param_ty={:?}", arg_param_ty);
match arg_param_ty.sty {
@ -295,7 +295,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
};
let ret_param_ty = projection.skip_binder().ty;
let ret_param_ty = self.resolve_type_vars_if_possible(&ret_param_ty);
let ret_param_ty = self.resolve_vars_if_possible(&ret_param_ty);
debug!("deduce_sig_from_projection: ret_param_ty={:?}", ret_param_ty);
let sig = self.tcx.mk_fn_sig(

View file

@ -575,7 +575,7 @@ impl<'f, 'gcx, 'tcx> Coerce<'f, 'gcx, 'tcx> {
// Uncertain or unimplemented.
Ok(None) => {
if trait_ref.def_id() == unsize_did {
let trait_ref = self.resolve_type_vars_if_possible(&trait_ref);
let trait_ref = self.resolve_vars_if_possible(&trait_ref);
let self_ty = trait_ref.skip_binder().self_ty();
let unsize_ty = trait_ref.skip_binder().input_types().nth(1).unwrap();
debug!("coerce_unsized: ambiguous unsize case for {:?}", trait_ref);

View file

@ -48,7 +48,7 @@ impl<'a, 'gcx, 'tcx> InteriorVisitor<'a, 'gcx, 'tcx> {
});
if let Some(yield_span) = live_across_yield {
let ty = self.fcx.resolve_type_vars_if_possible(&ty);
let ty = self.fcx.resolve_vars_if_possible(&ty);
debug!("type in expr = {:?}, scope = {:?}, type = {:?}, count = {}, yield_span = {:?}",
expr, scope, ty, self.expr_count, yield_span);

View file

@ -511,7 +511,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> {
let base_ty = self.tables.borrow().expr_adjustments(base_expr).last()
.map_or_else(|| self.node_ty(expr.hir_id), |adj| adj.target);
let base_ty = self.resolve_type_vars_if_possible(&base_ty);
let base_ty = self.resolve_vars_if_possible(&base_ty);
// Need to deref because overloaded place ops take self by-reference.
let base_ty = base_ty.builtin_deref(false)

View file

@ -253,7 +253,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
scope: ProbeScope)
-> probe::PickResult<'tcx> {
let mode = probe::Mode::MethodCall;
let self_ty = self.resolve_type_vars_if_possible(&self_ty);
let self_ty = self.resolve_vars_if_possible(&self_ty);
self.probe_for_name(span, mode, method_name, IsSuggestion(false),
self_ty, call_expr.hir_id, scope)
}

View file

@ -1338,7 +1338,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
// and point at it rather than reporting the entire
// trait-ref?
result = ProbeResult::NoMatch;
let trait_ref = self.resolve_type_vars_if_possible(&trait_ref);
let trait_ref = self.resolve_vars_if_possible(&trait_ref);
possibly_unsatisfied_predicates.push(trait_ref);
}
}
@ -1351,7 +1351,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
// Evaluate those obligations to see if they might possibly hold.
for o in candidate_obligations.into_iter().chain(sub_obligations) {
let o = self.resolve_type_vars_if_possible(&o);
let o = self.resolve_vars_if_possible(&o);
if !self.predicate_may_hold(&o) {
result = ProbeResult::NoMatch;
if let &ty::Predicate::Trait(ref pred) = &o.predicate {
@ -1364,7 +1364,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> {
if let (Some(return_ty), Some(xform_ret_ty)) =
(self.return_type, probe.xform_ret_ty)
{
let xform_ret_ty = self.resolve_type_vars_if_possible(&xform_ret_ty);
let xform_ret_ty = self.resolve_vars_if_possible(&xform_ret_ty);
debug!("comparing return_ty {:?} with xform ret ty {:?}",
return_ty,
probe.xform_ret_ty);

View file

@ -196,7 +196,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}) => {
let tcx = self.tcx;
let actual = self.resolve_type_vars_if_possible(&rcvr_ty);
let actual = self.resolve_vars_if_possible(&rcvr_ty);
let ty_str = self.ty_to_string(actual);
let is_method = mode == Mode::MethodCall;
let item_kind = if is_method {

View file

@ -330,13 +330,13 @@ impl<'a, 'gcx, 'tcx> Expectation<'tcx> {
match self {
NoExpectation => NoExpectation,
ExpectCastableToType(t) => {
ExpectCastableToType(fcx.resolve_type_vars_if_possible(&t))
ExpectCastableToType(fcx.resolve_vars_if_possible(&t))
}
ExpectHasType(t) => {
ExpectHasType(fcx.resolve_type_vars_if_possible(&t))
ExpectHasType(fcx.resolve_vars_if_possible(&t))
}
ExpectRvalueLikeUnsized(t) => {
ExpectRvalueLikeUnsized(fcx.resolve_type_vars_if_possible(&t))
ExpectRvalueLikeUnsized(fcx.resolve_vars_if_possible(&t))
}
}
}
@ -2067,7 +2067,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
/// Resolves type variables in `ty` if possible. Unlike the infcx
/// version (resolve_type_vars_if_possible), this version will
/// version (resolve_vars_if_possible), this version will
/// also select obligations if it seems useful, in an effort
/// to get more type information.
fn resolve_type_vars_with_obligations(&self, mut ty: Ty<'tcx>) -> Ty<'tcx> {
@ -2080,7 +2080,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
// If `ty` is a type variable, see whether we already know what it is.
ty = self.resolve_type_vars_if_possible(&ty);
ty = self.resolve_vars_if_possible(&ty);
if !ty.has_infer_types() {
debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
return ty;
@ -2091,7 +2091,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// indirect dependencies that don't seem worth tracking
// precisely.
self.select_obligations_where_possible(false);
ty = self.resolve_type_vars_if_possible(&ty);
ty = self.resolve_vars_if_possible(&ty);
debug!("resolve_type_vars_with_obligations: ty={:?}", ty);
ty
@ -2127,7 +2127,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
#[inline]
pub fn write_ty(&self, id: hir::HirId, ty: Ty<'tcx>) {
debug!("write_ty({:?}, {:?}) in fcx {}",
id, self.resolve_type_vars_if_possible(&ty), self.tag());
id, self.resolve_vars_if_possible(&ty), self.tag());
self.tables.borrow_mut().node_types_mut().insert(id, ty);
if ty.references_error() {
@ -2950,9 +2950,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
} else {
// is the missing argument of type `()`?
let sugg_unit = if expected_arg_tys.len() == 1 && supplied_arg_count == 0 {
self.resolve_type_vars_if_possible(&expected_arg_tys[0]).is_unit()
self.resolve_vars_if_possible(&expected_arg_tys[0]).is_unit()
} else if fn_inputs.len() == 1 && supplied_arg_count == 0 {
self.resolve_type_vars_if_possible(&fn_inputs[0]).is_unit()
self.resolve_vars_if_possible(&fn_inputs[0]).is_unit()
} else {
false
};
@ -3063,7 +3063,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
}
ty::FnDef(..) => {
let ptr_ty = self.tcx.mk_fn_ptr(arg_ty.fn_sig(self.tcx));
let ptr_ty = self.resolve_type_vars_if_possible(&ptr_ty);
let ptr_ty = self.resolve_vars_if_possible(&ptr_ty);
variadic_error(tcx.sess, arg.span, arg_ty, &ptr_ty.to_string());
}
_ => {}
@ -3253,7 +3253,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Record all the argument types, with the substitutions
// produced from the above subtyping unification.
Ok(formal_args.iter().map(|ty| {
self.resolve_type_vars_if_possible(ty)
self.resolve_vars_if_possible(ty)
}).collect())
}).unwrap_or_default();
debug!("expected_inputs_for_expected_output(formal={:?} -> {:?}, expected={:?} -> {:?})",
@ -4333,9 +4333,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
// Find the type of `e`. Supply hints based on the type we are casting to,
// if appropriate.
let t_cast = self.to_ty_saving_user_provided_ty(t);
let t_cast = self.resolve_type_vars_if_possible(&t_cast);
let t_cast = self.resolve_vars_if_possible(&t_cast);
let t_expr = self.check_expr_with_expectation(e, ExpectCastableToType(t_cast));
let t_cast = self.resolve_type_vars_if_possible(&t_cast);
let t_cast = self.resolve_vars_if_possible(&t_cast);
// Eagerly check for some obvious errors.
if t_expr.references_error() || t_cast.references_error() {

View file

@ -618,7 +618,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
method.sig.output()
}
Err(()) => {
let actual = self.resolve_type_vars_if_possible(&operand_ty);
let actual = self.resolve_vars_if_possible(&operand_ty);
if !actual.references_error() {
let mut err = struct_span_err!(self.tcx.sess, ex.span, E0600,
"cannot apply unary operator `{}` to type `{}`",

View file

@ -270,7 +270,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> {
/// of b will be `&<R0>.i32` and then `*b` will require that `<R0>` be bigger than the let and
/// the `*b` expression, so we will effectively resolve `<R0>` to be the block B.
pub fn resolve_type(&self, unresolved_ty: Ty<'tcx>) -> Ty<'tcx> {
self.resolve_type_vars_if_possible(&unresolved_ty)
self.resolve_vars_if_possible(&unresolved_ty)
}
/// Try to resolve the type for the given node.

View file

@ -138,7 +138,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
hir::ExprKind::Unary(hir::UnNeg, ref inner)
| hir::ExprKind::Unary(hir::UnNot, ref inner) => {
let inner_ty = self.fcx.node_ty(inner.hir_id);
let inner_ty = self.fcx.resolve_type_vars_if_possible(&inner_ty);
let inner_ty = self.fcx.resolve_vars_if_possible(&inner_ty);
if inner_ty.is_scalar() {
let mut tables = self.fcx.tables.borrow_mut();
@ -149,10 +149,10 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
hir::ExprKind::Binary(ref op, ref lhs, ref rhs)
| hir::ExprKind::AssignOp(ref op, ref lhs, ref rhs) => {
let lhs_ty = self.fcx.node_ty(lhs.hir_id);
let lhs_ty = self.fcx.resolve_type_vars_if_possible(&lhs_ty);
let lhs_ty = self.fcx.resolve_vars_if_possible(&lhs_ty);
let rhs_ty = self.fcx.node_ty(rhs.hir_id);
let rhs_ty = self.fcx.resolve_type_vars_if_possible(&rhs_ty);
let rhs_ty = self.fcx.resolve_vars_if_possible(&rhs_ty);
if lhs_ty.is_scalar() && rhs_ty.is_scalar() {
let mut tables = self.fcx.tables.borrow_mut();
@ -192,7 +192,7 @@ impl<'cx, 'gcx, 'tcx> WritebackCx<'cx, 'gcx, 'tcx> {
// All valid indexing looks like this; might encounter non-valid indexes at this point
if let ty::Ref(_, base_ty, _) = tables.expr_ty_adjusted(&base).sty {
let index_ty = tables.expr_ty_adjusted(&index);
let index_ty = self.fcx.resolve_type_vars_if_possible(&index_ty);
let index_ty = self.fcx.resolve_vars_if_possible(&index_ty);
if base_ty.builtin_index().is_some() && index_ty == self.fcx.tcx.types.usize {
// Remove the method call record

View file

@ -1,9 +1,11 @@
fn main() {
loop {
|_: [_; break]| {} //~ ERROR: `break` outside of loop
//~^ ERROR mismatched types
}
loop {
|_: [_; continue]| {} //~ ERROR: `continue` outside of loop
//~^ ERROR mismatched types
}
}

View file

@ -5,11 +5,30 @@ LL | |_: [_; break]| {}
| ^^^^^ cannot break outside of a loop
error[E0268]: `continue` outside of loop
--> $DIR/array-break-length.rs:7:17
--> $DIR/array-break-length.rs:8:17
|
LL | |_: [_; continue]| {}
| ^^^^^^^^ cannot break outside of a loop
error: aborting due to 2 previous errors
error[E0308]: mismatched types
--> $DIR/array-break-length.rs:3:9
|
LL | |_: [_; break]| {}
| ^^^^^^^^^^^^^^^^^^ expected (), found closure
|
= note: expected type `()`
found type `[closure@$DIR/array-break-length.rs:3:9: 3:27]`
For more information about this error, try `rustc --explain E0268`.
error[E0308]: mismatched types
--> $DIR/array-break-length.rs:8:9
|
LL | |_: [_; continue]| {}
| ^^^^^^^^^^^^^^^^^^^^^ expected (), found closure
|
= note: expected type `()`
found type `[closure@$DIR/array-break-length.rs:8:9: 8:30]`
error: aborting due to 4 previous errors
Some errors have detailed explanations: E0268, E0308.
For more information about an error, try `rustc --explain E0268`.

View file

@ -2,6 +2,8 @@ fn main() {
|_: [_; continue]| {}; //~ ERROR: `continue` outside of loop
while |_: [_; continue]| {} {} //~ ERROR: `continue` outside of loop
//~^ ERROR mismatched types
while |_: [_; break]| {} {} //~ ERROR: `break` outside of loop
//~^ ERROR mismatched types
}

View file

@ -11,11 +11,30 @@ LL | while |_: [_; continue]| {} {}
| ^^^^^^^^ cannot break outside of a loop
error[E0268]: `break` outside of loop
--> $DIR/closure-array-break-length.rs:6:19
--> $DIR/closure-array-break-length.rs:7:19
|
LL | while |_: [_; break]| {} {}
| ^^^^^ cannot break outside of a loop
error: aborting due to 3 previous errors
error[E0308]: mismatched types
--> $DIR/closure-array-break-length.rs:4:11
|
LL | while |_: [_; continue]| {} {}
| ^^^^^^^^^^^^^^^^^^^^^ expected bool, found closure
|
= note: expected type `bool`
found type `[closure@$DIR/closure-array-break-length.rs:4:11: 4:32]`
For more information about this error, try `rustc --explain E0268`.
error[E0308]: mismatched types
--> $DIR/closure-array-break-length.rs:7:11
|
LL | while |_: [_; break]| {} {}
| ^^^^^^^^^^^^^^^^^^ expected bool, found closure
|
= note: expected type `bool`
found type `[closure@$DIR/closure-array-break-length.rs:7:11: 7:29]`
error: aborting due to 5 previous errors
Some errors have detailed explanations: E0268, E0308.
For more information about an error, try `rustc --explain E0268`.

View file

@ -0,0 +1,17 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
pub trait Foo {
fn foo(&self);
}
impl<T, const N: usize> Foo for [T; N] {
fn foo(&self) {
let _ = &self;
}
}
fn main() {}

View file

@ -0,0 +1,6 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/broken-mir-1.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^

View file

@ -0,0 +1,9 @@
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
use std::fmt::Debug;
#[derive(Debug)]
struct S<T: Debug, const N: usize>([T; N]); //~ ERROR `[T; _]` doesn't implement `std::fmt::Debug`
fn main() {}

View file

@ -0,0 +1,19 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/broken-mir-2.rs:1:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^
error[E0277]: `[T; _]` doesn't implement `std::fmt::Debug`
--> $DIR/broken-mir-2.rs:7:36
|
LL | struct S<T: Debug, const N: usize>([T; N]);
| ^^^^^^ `[T; _]` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug`
|
= help: the trait `std::fmt::Debug` is not implemented for `[T; _]`
= note: required because of the requirements on the impl of `std::fmt::Debug` for `&[T; _]`
= note: required for the cast to the object type `dyn std::fmt::Debug`
error: aborting due to previous error
For more information about this error, try `rustc --explain E0277`.

View file

@ -8,4 +8,5 @@ struct Foo<const NUM_BYTES: usize>(pub [u8; NUM_BYTES]);
fn main() {
let _ = Foo::<3>([1, 2, 3]); //~ ERROR type annotations needed
//~^ ERROR mismatched types
}

View file

@ -10,6 +10,16 @@ error[E0282]: type annotations needed
LL | let _ = Foo::<3>([1, 2, 3]);
| ^ cannot infer type for `{integer}`
error: aborting due to previous error
error[E0308]: mismatched types
--> $DIR/cannot-infer-type-for-const-param.rs:10:22
|
LL | let _ = Foo::<3>([1, 2, 3]);
| ^^^^^^^^^ expected `3`, found `3usize`
|
= note: expected type `[u8; _]`
found type `[u8; 3]`
For more information about this error, try `rustc --explain E0282`.
error: aborting due to 2 previous errors
Some errors have detailed explanations: E0282, E0308.
For more information about an error, try `rustc --explain E0282`.

View file

@ -0,0 +1,16 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
use std::fmt::Display;
fn print_slice<T: Display, const N: usize>(slice: &[T; N]) {
for x in slice.iter() {
println!("{}", x);
}
}
fn main() {
print_slice(&[1, 2, 3]);
}

View file

@ -0,0 +1,6 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/fn-taking-const-generic-array.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^

View file

@ -0,0 +1,18 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
use std::fmt;
struct Array<T, const N: usize>([T; N]);
impl<T: fmt::Debug, const N: usize> fmt::Debug for Array<T, {N}> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list().entries(self.0.iter()).finish()
}
}
fn main() {
assert_eq!(format!("{:?}", Array([1, 2, 3])), "[1, 2, 3]");
}

View file

@ -0,0 +1,6 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/uninferred-consts-during-codegen-1.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^

View file

@ -0,0 +1,18 @@
// run-pass
#![feature(const_generics)]
//~^ WARN the feature `const_generics` is incomplete and may cause the compiler to crash
use std::fmt;
struct Array<T>(T);
impl<T: fmt::Debug, const N: usize> fmt::Debug for Array<[T; N]> {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
f.debug_list().entries((&self.0 as &[T]).iter()).finish()
}
}
fn main() {
assert_eq!(format!("{:?}", Array([1, 2, 3])), "[1, 2, 3]");
}

View file

@ -0,0 +1,6 @@
warning: the feature `const_generics` is incomplete and may cause the compiler to crash
--> $DIR/uninferred-consts-during-codegen-2.rs:3:12
|
LL | #![feature(const_generics)]
| ^^^^^^^^^^^^^^

View file

@ -4,8 +4,12 @@ const ARR: [i32; 6] = [42, 43, 44, 45, 46, 47];
const IDX: usize = 3;
const VAL: i32 = ARR[IDX];
const BONG: [i32; (ARR[0] - 41) as usize] = [5];
const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; //~ ERROR: mismatched types
const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99]; //~ ERROR: mismatched types
const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
//~^ ERROR: mismatched types
//~| expected an array with a fixed size of 2 elements, found one with 1 element
const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
//~^ ERROR: mismatched types
//~| expected an array with a fixed size of 1 element, found one with 2 elements
fn main() {
let _ = VAL;

View file

@ -2,16 +2,16 @@ error[E0308]: mismatched types
--> $DIR/const-array-oob-arith.rs:7:45
|
LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5];
| ^^^ expected an array with a fixed size of 2 elements, found one with 1 elements
| ^^^ expected an array with a fixed size of 2 elements, found one with 1 element
|
= note: expected type `[i32; 2]`
found type `[i32; 1]`
error[E0308]: mismatched types
--> $DIR/const-array-oob-arith.rs:8:44
--> $DIR/const-array-oob-arith.rs:10:44
|
LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99];
| ^^^^^^^ expected an array with a fixed size of 1 elements, found one with 2 elements
| ^^^^^^^ expected an array with a fixed size of 1 element, found one with 2 elements
|
= note: expected type `[i32; 1]`
found type `[i32; 2]`

View file

@ -13,5 +13,5 @@ fn main() {
//~^ ERROR mismatched types
//~| expected type `(isize, f64)`
//~| found type `(isize,)`
//~| expected a tuple with 2 elements, found one with 1 elements
//~| expected a tuple with 2 elements, found one with 1 element
}

View file

@ -11,7 +11,7 @@ error[E0308]: mismatched types
--> $DIR/tuple-arity-mismatch.rs:12:20
|
LL | let y = first ((1,));
| ^^^^ expected a tuple with 2 elements, found one with 1 elements
| ^^^^ expected a tuple with 2 elements, found one with 1 element
|
= note: expected type `(isize, f64)`
found type `(isize,)`

View file

@ -3,4 +3,5 @@ fn main() {
const l: usize = v.count(); //~ ERROR attempt to use a non-constant value in a constant
let s: [u32; l] = v.into_iter().collect();
//~^ ERROR evaluation of constant value failed
//~^^ ERROR a collection of type
}

View file

@ -10,7 +10,15 @@ error[E0080]: evaluation of constant value failed
LL | let s: [u32; l] = v.into_iter().collect();
| ^ referenced constant has errors
error: aborting due to 2 previous errors
error[E0277]: a collection of type `[u32; _]` cannot be built from an iterator over elements of type `{integer}`
--> $DIR/type-dependent-def-issue-49241.rs:4:37
|
LL | let s: [u32; l] = v.into_iter().collect();
| ^^^^^^^ a collection of type `[u32; _]` cannot be built from `std::iter::Iterator<Item={integer}>`
|
= help: the trait `std::iter::FromIterator<{integer}>` is not implemented for `[u32; _]`
Some errors have detailed explanations: E0080, E0435.
error: aborting due to 3 previous errors
Some errors have detailed explanations: E0080, E0277, E0435.
For more information about an error, try `rustc --explain E0080`.