From 73f7e426be348e9d479c8685843399b9cbbff064 Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 May 2019 18:01:50 +0100 Subject: [PATCH 01/17] Relate identical parameters in array lengths --- src/librustc/ty/relate.rs | 38 +++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 75d227d8067..70c47a6ca34 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -9,7 +9,6 @@ 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 std::rc::Rc; use std::iter; @@ -474,8 +473,9 @@ 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 { - match x.val { + + let to_u64 = |ct: &'tcx ty::Const<'tcx>| -> Option { + match ct.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) => { @@ -493,26 +493,18 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, instance, promoted: None, }; - if let Some(s) = tcx.const_eval(param_env.and(cid)) - .ok() - .map(|c| c.unwrap_usize(tcx)) { - return Ok(s) - } + return tcx.const_eval(param_env.and(cid)) + .ok() + .map(|c| c.unwrap_usize(tcx)); } } - tcx.sess.delay_span_bug(tcx.def_span(def_id), - "array length could not be evaluated"); - Err(ErrorReported) + None } - _ => x.assert_usize(tcx).ok_or_else(|| { - tcx.sess.delay_span_bug(DUMMY_SP, - "array length could not be evaluated"); - ErrorReported - }) + _ => ct.assert_usize(tcx), } }; - match (to_u64(*sz_a), to_u64(*sz_b)) { - (Ok(sz_a_u64), Ok(sz_b_u64)) => { + match (to_u64(sz_a), to_u64(sz_b)) { + (Some(sz_a_u64), Some(sz_b_u64)) => { if sz_a_u64 == sz_b_u64 { Ok(tcx.mk_ty(ty::Array(t, sz_a))) } else { @@ -520,9 +512,13 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, 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) + _ => { + if let Ok(sz) = relation.relate(&sz_a, &sz_b) { + Ok(tcx.mk_ty(ty::Array(t, sz))) + } else { + tcx.sess.delay_span_bug(DUMMY_SP, "array length could not be evaluated"); + Ok(tcx.types.err) + } } } } From 5a585fe45e93b946013ec2eebb0b2c2ec3bed15a Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 May 2019 18:02:05 +0100 Subject: [PATCH 02/17] Add a test for a function taking a const param array as an argument --- .../fn-taking-const-generic-array.rs | 16 ++++++++++++++++ .../fn-taking-const-generic-array.stderr | 6 ++++++ 2 files changed, 22 insertions(+) create mode 100644 src/test/ui/const-generics/fn-taking-const-generic-array.rs create mode 100644 src/test/ui/const-generics/fn-taking-const-generic-array.stderr diff --git a/src/test/ui/const-generics/fn-taking-const-generic-array.rs b/src/test/ui/const-generics/fn-taking-const-generic-array.rs new file mode 100644 index 00000000000..d3d17cca4da --- /dev/null +++ b/src/test/ui/const-generics/fn-taking-const-generic-array.rs @@ -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(slice: &[T; N]) { + for x in slice.iter() { + println!("{}", x); + } +} + +fn main() { + print_slice(&[1, 2, 3]); +} diff --git a/src/test/ui/const-generics/fn-taking-const-generic-array.stderr b/src/test/ui/const-generics/fn-taking-const-generic-array.stderr new file mode 100644 index 00000000000..36704128325 --- /dev/null +++ b/src/test/ui/const-generics/fn-taking-const-generic-array.stderr @@ -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)] + | ^^^^^^^^^^^^^^ + From 4ad5c62550aa402716f9c845e8fdfc1c89e8a4fa Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 May 2019 18:54:14 +0100 Subject: [PATCH 03/17] Resolve consts in OpportunisticTypeResolver --- src/librustc/infer/resolve.rs | 15 ++++++++++++--- src/librustc/traits/codegen/mod.rs | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index 079385368f8..e9a4805c439 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -1,6 +1,6 @@ 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}; /////////////////////////////////////////////////////////////////////////// @@ -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) } } } diff --git a/src/librustc/traits/codegen/mod.rs b/src/librustc/traits/codegen/mod.rs index 7e3d6d752cc..fa8e87cb859 100644 --- a/src/librustc/traits/codegen/mod.rs +++ b/src/librustc/traits/codegen/mod.rs @@ -157,7 +157,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { 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) ) } } From 55dcc20f9a605e19d3c34bfc7f84380f079350fb Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 May 2019 18:58:15 +0100 Subject: [PATCH 04/17] Add tests for uninferred consts during codegen --- .../uninferred-consts-during-codegen-1.rs | 18 ++++++++++++++++++ .../uninferred-consts-during-codegen-1.stderr | 6 ++++++ .../uninferred-consts-during-codegen-2.rs | 18 ++++++++++++++++++ .../uninferred-consts-during-codegen-2.stderr | 6 ++++++ 4 files changed, 48 insertions(+) create mode 100644 src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs create mode 100644 src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr create mode 100644 src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs create mode 100644 src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs new file mode 100644 index 00000000000..2e555d11aba --- /dev/null +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs @@ -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; N]); + +impl fmt::Debug for Array { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + f.debug_list().entries(self.0.iter()).finish() + } +} + +fn main() { + println!("{:?}", Array([1, 2, 3])); +} diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr new file mode 100644 index 00000000000..eb2e446396c --- /dev/null +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.stderr @@ -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)] + | ^^^^^^^^^^^^^^ + diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs new file mode 100644 index 00000000000..7a1a4f49794 --- /dev/null +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs @@ -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); + +impl 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() { + println!("{:?}", Array([1, 2, 3])); +} diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr new file mode 100644 index 00000000000..eaa20bb7892 --- /dev/null +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.stderr @@ -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)] + | ^^^^^^^^^^^^^^ + From c94ba6382d274d5b1ce9ef9a8392ec7351a4714b Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 11 May 2019 19:08:26 +0100 Subject: [PATCH 05/17] Rename `OpportunisticTypeResolver` to `OpportunisticVarResolver` --- src/librustc/infer/error_reporting/mod.rs | 6 ++--- .../infer/error_reporting/need_type_info.rs | 6 ++--- .../nice_region_error/placeholder_error.rs | 4 +-- src/librustc/infer/fudge.rs | 2 +- src/librustc/infer/mod.rs | 20 +++++++------- src/librustc/infer/opaque_types/mod.rs | 4 +-- src/librustc/infer/outlives/env.rs | 2 +- src/librustc/infer/outlives/obligations.rs | 4 +-- src/librustc/infer/resolve.rs | 14 +++++----- src/librustc/middle/mem_categorization.rs | 8 +++--- src/librustc/traits/auto_trait.rs | 6 ++--- src/librustc/traits/chalk_fulfill.rs | 2 +- src/librustc/traits/codegen/mod.rs | 2 +- src/librustc/traits/coherence.rs | 4 +-- src/librustc/traits/error_reporting.rs | 26 +++++++++---------- src/librustc/traits/fulfill.rs | 10 +++---- src/librustc/traits/mod.rs | 2 +- src/librustc/traits/project.rs | 6 ++--- src/librustc/traits/query/dropck_outlives.rs | 2 +- src/librustc/traits/query/type_op/custom.rs | 2 +- src/librustc/traits/select.rs | 6 ++--- src/librustc/traits/specialize/mod.rs | 2 +- .../borrow_check/nll/type_check/mod.rs | 2 +- src/librustc_traits/chalk_context/mod.rs | 2 +- .../chalk_context/program_clauses/mod.rs | 2 +- .../chalk_context/resolvent_ops.rs | 4 +-- .../implied_outlives_bounds.rs | 2 +- .../normalize_erasing_regions.rs | 2 +- src/librustc_typeck/check/_match.rs | 2 +- src/librustc_typeck/check/autoderef.rs | 6 ++--- src/librustc_typeck/check/cast.rs | 4 +-- src/librustc_typeck/check/closure.rs | 4 +-- src/librustc_typeck/check/coercion.rs | 2 +- .../check/generator_interior.rs | 2 +- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 2 +- src/librustc_typeck/check/method/probe.rs | 6 ++--- src/librustc_typeck/check/method/suggest.rs | 2 +- src/librustc_typeck/check/mod.rs | 26 +++++++++---------- src/librustc_typeck/check/op.rs | 2 +- src/librustc_typeck/check/regionck.rs | 2 +- src/librustc_typeck/check/writeback.rs | 8 +++--- 42 files changed, 111 insertions(+), 113 deletions(-) diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 8ec9d42ec5f..f87c6977f33 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -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>, ) -> 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, ) -> 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; } diff --git a/src/librustc/infer/error_reporting/need_type_info.rs b/src/librustc/infer/error_reporting/need_type_info.rs index ca159872ea7..972ffbe1820 100644 --- a/src/librustc/infer/error_reporting/need_type_info.rs +++ b/src/librustc/infer/error_reporting/need_type_info.rs @@ -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, diff --git a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs index 60acbe0afe4..1dd39195025 100644 --- a/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs +++ b/src/librustc/infer/error_reporting/nice_region_error/placeholder_error.rs @@ -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, }); diff --git a/src/librustc/infer/fudge.rs b/src/librustc/infer/fudge.rs index 5f5a2d4a489..7461d8bc728 100644 --- a/src/librustc/infer/fudge.rs +++ b/src/librustc/infer/fudge.rs @@ -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 diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index b5a9184079a..a4a7efdbc9e 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -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(&self, value: &T) -> T + pub fn resolve_vars_if_possible(&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(&self, value: &T) -> Option<(Ty<'tcx>, Option)> 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. diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 4351f94df2f..3f114595597 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -284,9 +284,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { debug!("constrain_opaque_type: def_id={:?}", def_id); debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn); - 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); diff --git a/src/librustc/infer/outlives/env.rs b/src/librustc/infer/outlives/env.rs index 39aa51a95f7..3e626999200 100644 --- a/src/librustc/infer/outlives/env.rs +++ b/src/librustc/infer/outlives/env.rs @@ -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) diff --git a/src/librustc/infer/outlives/obligations.rs b/src/librustc/infer/outlives/obligations.rs index ee660328485..90b3be21385 100644 --- a/src/librustc/infer/outlives/obligations.rs +++ b/src/librustc/infer/outlives/obligations.rs @@ -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); } } diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index e9a4805c439..98f63c803ca 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -4,25 +4,25 @@ use crate::ty::{self, Ty, Const, TyCtxt, TypeFoldable, InferConst, TypeFlags}; use crate::ty::fold::{TypeFolder, TypeVisitor}; /////////////////////////////////////////////////////////////////////////// -// OPPORTUNISTIC TYPE RESOLVER +// OPPORTUNISTIC KIND 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 kind 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 } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index c6b544469b5..8d7c6f18a85 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -458,10 +458,10 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { .unwrap_or(true) } - fn resolve_type_vars_if_possible(&self, value: &T) -> T + fn resolve_vars_if_possible(&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> { 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> { 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. diff --git a/src/librustc/traits/auto_trait.rs b/src/librustc/traits/auto_trait.rs index 2fa896962da..7505b3c1be8 100644 --- a/src/librustc/traits/auto_trait.rs +++ b/src/librustc/traits/auto_trait.rs @@ -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 diff --git a/src/librustc/traits/chalk_fulfill.rs b/src/librustc/traits/chalk_fulfill.rs index d9eb6d8157d..a7b5e6cf41b 100644 --- a/src/librustc/traits/chalk_fulfill.rs +++ b/src/librustc/traits/chalk_fulfill.rs @@ -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), diff --git a/src/librustc/traits/codegen/mod.rs b/src/librustc/traits/codegen/mod.rs index fa8e87cb859..591557eb2be 100644 --- a/src/librustc/traits/codegen/mod.rs +++ b/src/librustc/traits/codegen/mod.rs @@ -153,7 +153,7 @@ 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(|| diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index afbce5a4f0a..c6521a931bb 100644 --- a/src/librustc/traits/coherence.rs +++ b/src/librustc/traits/coherence.rs @@ -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); diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 9019c4a0575..5a2bf07b065 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -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 { 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; diff --git a/src/librustc/traits/fulfill.rs b/src/librustc/traits/fulfill.rs index 96212d829d4..c7943d16885 100644 --- a/src/librustc/traits/fulfill.rs +++ b/src/librustc/traits/fulfill.rs @@ -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 }) diff --git a/src/librustc/traits/mod.rs b/src/librustc/traits/mod.rs index 4b555e54f39..c135b0b759c 100644 --- a/src/librustc/traits/mod.rs +++ b/src/librustc/traits/mod.rs @@ -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) } diff --git a/src/librustc/traits/project.rs b/src/librustc/traits/project.rs index 92d5d4f0319..88bb3172c5e 100644 --- a/src/librustc/traits/project.rs +++ b/src/librustc/traits/project.rs @@ -312,7 +312,7 @@ impl<'a, 'b, 'gcx, 'tcx> AssocTypeNormalizer<'a, 'b, 'gcx, 'tcx> { } fn fold>(&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) }) } } diff --git a/src/librustc/traits/query/dropck_outlives.rs b/src/librustc/traits/query/dropck_outlives.rs index 5800b024ad2..c4aa14d2b7e 100644 --- a/src/librustc/traits/query/dropck_outlives.rs +++ b/src/librustc/traits/query/dropck_outlives.rs @@ -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, diff --git a/src/librustc/traits/query/type_op/custom.rs b/src/librustc/traits/query/type_op/custom.rs index 7e38282cc1a..5933d2366e8 100644 --- a/src/librustc/traits/query/type_op/custom.rs +++ b/src/librustc/traits/query/type_op/custom.rs @@ -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)), ®ion_constraint_data, ); diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index ec5e127a5ec..ba96233b853 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -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!( diff --git a/src/librustc/traits/specialize/mod.rs b/src/librustc/traits/specialize/mod.rs index 5da4a1b9c5f..b5d45d040fb 100644 --- a/src/librustc/traits/specialize/mod.rs +++ b/src/librustc/traits/specialize/mod.rs @@ -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)) } } }) diff --git a/src/librustc_mir/borrow_check/nll/type_check/mod.rs b/src/librustc_mir/borrow_check/nll/type_check/mod.rs index de8e75ca277..20b7f7eef0a 100644 --- a/src/librustc_mir/borrow_check/nll/type_check/mod.rs +++ b/src/librustc_mir/borrow_check/nll/type_check/mod.rs @@ -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 diff --git a/src/librustc_traits/chalk_context/mod.rs b/src/librustc_traits/chalk_context/mod.rs index 04cd632b297..96c647ca31e 100644 --- a/src/librustc_traits/chalk_context/mod.rs +++ b/src/librustc_traits/chalk_context/mod.rs @@ -411,7 +411,7 @@ impl context::UnificationOps, ChalkArenas<'tcx>> } fn debug_ex_clause(&mut self, value: &'v ChalkExClause<'tcx>) -> Box { - let string = format!("{:?}", self.infcx.resolve_type_vars_if_possible(value)); + let string = format!("{:?}", self.infcx.resolve_vars_if_possible(value)); Box::new(string) } diff --git a/src/librustc_traits/chalk_context/program_clauses/mod.rs b/src/librustc_traits/chalk_context/program_clauses/mod.rs index 7ce450c7039..c1f14cd3f8e 100644 --- a/src/librustc_traits/chalk_context/program_clauses/mod.rs +++ b/src/librustc_traits/chalk_context/program_clauses/mod.rs @@ -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); diff --git a/src/librustc_traits/chalk_context/resolvent_ops.rs b/src/librustc_traits/chalk_context/resolvent_ops.rs index 9d234e93b83..f1b8588790b 100644 --- a/src/librustc_traits/chalk_context/resolvent_ops.rs +++ b/src/librustc_traits/chalk_context/resolvent_ops.rs @@ -111,8 +111,8 @@ impl context::ResolventOps, ChalkArenas<'tcx>> ) -> Fallible> { 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( diff --git a/src/librustc_traits/implied_outlives_bounds.rs b/src/librustc_traits/implied_outlives_bounds.rs index b1688a7fbbb..73bb3fb5b9a 100644 --- a/src/librustc_traits/implied_outlives_bounds.rs +++ b/src/librustc_traits/implied_outlives_bounds.rs @@ -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) diff --git a/src/librustc_traits/normalize_erasing_regions.rs b/src/librustc_traits/normalize_erasing_regions.rs index 412d2ca6dfc..24fa5e97752 100644 --- a/src/librustc_traits/normalize_erasing_regions.rs +++ b/src/librustc_traits/normalize_erasing_regions.rs @@ -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() } diff --git a/src/librustc_typeck/check/_match.rs b/src/librustc_typeck/check/_match.rs index a74a33b7448..5a84e0cb85a 100644 --- a/src/librustc_typeck/check/_match.rs +++ b/src/librustc_typeck/check/_match.rs @@ -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); diff --git a/src/librustc_typeck/check/autoderef.rs b/src/librustc_typeck/check/autoderef.rs index f863cfe1887..38c3ee77636 100644 --- a/src/librustc_typeck/check/autoderef.rs +++ b/src/librustc_typeck/check/autoderef.rs @@ -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 { diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs index 4689456d11f..f8cad733ca1 100644 --- a/src/librustc_typeck/check/cast.rs +++ b/src/librustc_typeck/check/cast.rs @@ -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) => { diff --git a/src/librustc_typeck/check/closure.rs b/src/librustc_typeck/check/closure.rs index 3fa192f16f3..419f61b0ee2 100644 --- a/src/librustc_typeck/check/closure.rs +++ b/src/librustc_typeck/check/closure.rs @@ -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( diff --git a/src/librustc_typeck/check/coercion.rs b/src/librustc_typeck/check/coercion.rs index 90b2643d165..d64be24f753 100644 --- a/src/librustc_typeck/check/coercion.rs +++ b/src/librustc_typeck/check/coercion.rs @@ -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); diff --git a/src/librustc_typeck/check/generator_interior.rs b/src/librustc_typeck/check/generator_interior.rs index 08809917ba2..3785c3c8684 100644 --- a/src/librustc_typeck/check/generator_interior.rs +++ b/src/librustc_typeck/check/generator_interior.rs @@ -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); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index f93d5449e8b..493486321ac 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -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) diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 65bc06b65e1..213d53cf482 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -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) } diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 596ce008099..d78e0137082 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -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); diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index dfe21edee41..d2fcb987bc2 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -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 { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index f60ad5547a2..8701d751f2d 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -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() { diff --git a/src/librustc_typeck/check/op.rs b/src/librustc_typeck/check/op.rs index cd207478f8f..0bab63582aa 100644 --- a/src/librustc_typeck/check/op.rs +++ b/src/librustc_typeck/check/op.rs @@ -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 `{}`", diff --git a/src/librustc_typeck/check/regionck.rs b/src/librustc_typeck/check/regionck.rs index 353b9ac6cc3..62c9c7c8b1c 100644 --- a/src/librustc_typeck/check/regionck.rs +++ b/src/librustc_typeck/check/regionck.rs @@ -270,7 +270,7 @@ impl<'a, 'gcx, 'tcx> RegionCtxt<'a, 'gcx, 'tcx> { /// of b will be `&.i32` and then `*b` will require that `` be bigger than the let and /// the `*b` expression, so we will effectively resolve `` 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. diff --git a/src/librustc_typeck/check/writeback.rs b/src/librustc_typeck/check/writeback.rs index 13baf667808..a856013b719 100644 --- a/src/librustc_typeck/check/writeback.rs +++ b/src/librustc_typeck/check/writeback.rs @@ -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 From 908d97d03ce4d20287163d91a71695f03f3a906e Mon Sep 17 00:00:00 2001 From: varkor Date: Sun, 12 May 2019 22:28:26 +0100 Subject: [PATCH 06/17] Update test output --- src/test/ui/array-break-length.rs | 2 ++ src/test/ui/array-break-length.stderr | 25 ++++++++++++++++--- .../ui/closures/closure-array-break-length.rs | 2 ++ .../closure-array-break-length.stderr | 25 ++++++++++++++++--- .../ui/type/type-dependent-def-issue-49241.rs | 1 + .../type-dependent-def-issue-49241.stderr | 12 +++++++-- 6 files changed, 59 insertions(+), 8 deletions(-) diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs index ab15ce6e8d8..2696aea5e89 100644 --- a/src/test/ui/array-break-length.rs +++ b/src/test/ui/array-break-length.rs @@ -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 } } diff --git a/src/test/ui/array-break-length.stderr b/src/test/ui/array-break-length.stderr index 1cbf77a99f8..0e0dc8f623e 100644 --- a/src/test/ui/array-break-length.stderr +++ b/src/test/ui/array-break-length.stderr @@ -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`. diff --git a/src/test/ui/closures/closure-array-break-length.rs b/src/test/ui/closures/closure-array-break-length.rs index ac17bfdc941..a7f16d70ba8 100644 --- a/src/test/ui/closures/closure-array-break-length.rs +++ b/src/test/ui/closures/closure-array-break-length.rs @@ -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 } diff --git a/src/test/ui/closures/closure-array-break-length.stderr b/src/test/ui/closures/closure-array-break-length.stderr index 9b78aa16a58..46fbd3e0fae 100644 --- a/src/test/ui/closures/closure-array-break-length.stderr +++ b/src/test/ui/closures/closure-array-break-length.stderr @@ -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`. diff --git a/src/test/ui/type/type-dependent-def-issue-49241.rs b/src/test/ui/type/type-dependent-def-issue-49241.rs index 51bd116fbd6..5ad50ffcbc3 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.rs +++ b/src/test/ui/type/type-dependent-def-issue-49241.rs @@ -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 } diff --git a/src/test/ui/type/type-dependent-def-issue-49241.stderr b/src/test/ui/type/type-dependent-def-issue-49241.stderr index 25cae8d9e49..851004d1058 100644 --- a/src/test/ui/type/type-dependent-def-issue-49241.stderr +++ b/src/test/ui/type/type-dependent-def-issue-49241.stderr @@ -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` + | + = 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`. From d5c6cb87784ea5c82177beb2662ccdc6c4751388 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 13 May 2019 21:15:08 +0100 Subject: [PATCH 07/17] Eagerly evaluate in `super_relate_consts` --- src/librustc/ty/relate.rs | 93 ++++++++----------- .../ui/consts/const-array-oob-arith.stderr | 4 +- 2 files changed, 39 insertions(+), 58 deletions(-) diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 70c47a6ca34..55525d868e2 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -8,8 +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 syntax_pos::DUMMY_SP; +use crate::mir::interpret::{ConstValue, Scalar, GlobalId}; use std::rc::Rc; use std::iter; use rustc_target::spec::abi; @@ -473,54 +472,8 @@ 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 = |ct: &'tcx ty::Const<'tcx>| -> Option { - match ct.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, - }; - return tcx.const_eval(param_env.and(cid)) - .ok() - .map(|c| c.unwrap_usize(tcx)); - } - } - None - } - _ => ct.assert_usize(tcx), - } - }; - match (to_u64(sz_a), to_u64(sz_b)) { - (Some(sz_a_u64), Some(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))) - } - } - _ => { - if let Ok(sz) = relation.relate(&sz_a, &sz_b) { - Ok(tcx.mk_ty(ty::Array(t, sz))) - } else { - tcx.sess.delay_span_bug(DUMMY_SP, "array length could not be evaluated"); - Ok(tcx.types.err) - } - } - } + let sz = relation.relate(&sz_a, &sz_b)?; + Ok(tcx.mk_ty(ty::Array(t, sz))) } (&ty::Slice(a_t), &ty::Slice(b_t)) => @@ -594,11 +547,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) @@ -609,8 +587,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!( @@ -631,9 +614,7 @@ where })) } - _ => { - Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))) - } + _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), } } diff --git a/src/test/ui/consts/const-array-oob-arith.stderr b/src/test/ui/consts/const-array-oob-arith.stderr index 00286b0b0e0..29297b24e98 100644 --- a/src/test/ui/consts/const-array-oob-arith.stderr +++ b/src/test/ui/consts/const-array-oob-arith.stderr @@ -2,7 +2,7 @@ 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 `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 2 }) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 1 }) }` | = note: expected type `[i32; 2]` found type `[i32; 1]` @@ -11,7 +11,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:8: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 `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 1 }) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 2 }) }` | = note: expected type `[i32; 1]` found type `[i32; 2]` From 193b748d5fa1f056263be641e42f2b4b1801387d Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 13 May 2019 21:24:00 +0100 Subject: [PATCH 08/17] Remove FixedArraySize error --- src/librustc/infer/opaque_types/mod.rs | 2 ++ src/librustc/ty/error.rs | 7 ------- src/librustc/ty/structural_impls.rs | 2 -- 3 files changed, 2 insertions(+), 9 deletions(-) diff --git a/src/librustc/infer/opaque_types/mod.rs b/src/librustc/infer/opaque_types/mod.rs index 3f114595597..220b7b5fa67 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -284,6 +284,8 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { debug!("constrain_opaque_type: def_id={:?}", def_id); debug!("constrain_opaque_type: opaque_defn={:#?}", opaque_defn); + let tcx = self.tcx; + let concrete_ty = self.resolve_vars_if_possible(&opaque_defn.concrete_ty); debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty); diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 4e4024d5bab..9bf1dbe2958 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -23,7 +23,6 @@ pub enum TypeError<'tcx> { AbiMismatch(ExpectedFound), Mutability, TupleSize(ExpectedFound), - FixedArraySize(ExpectedFound), ArgCount, RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>), @@ -94,12 +93,6 @@ 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", diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index 0daa567052d..b0062f20e7f 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -716,7 +716,6 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { AbiMismatch(x) => AbiMismatch(x), Mutability => Mutability, TupleSize(x) => TupleSize(x), - FixedArraySize(x) => FixedArraySize(x), ArgCount => ArgCount, RegionsDoesNotOutlive(a, b) => { return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)) @@ -1295,7 +1294,6 @@ EnumTypeFoldableImpl! { (ty::error::TypeError::AbiMismatch)(x), (ty::error::TypeError::Mutability), (ty::error::TypeError::TupleSize)(x), - (ty::error::TypeError::FixedArraySize)(x), (ty::error::TypeError::ArgCount), (ty::error::TypeError::RegionsDoesNotOutlive)(a, b), (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b), From 57ff5899d22fd0b898784b3b55b1dacad27664c6 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 20 May 2019 23:03:38 +0100 Subject: [PATCH 09/17] Add broken MIR regression tests --- src/test/ui/const-generics/broken-mir-1.rs | 17 +++++++++++++++++ .../ui/const-generics/broken-mir-1.stderr | 6 ++++++ src/test/ui/const-generics/broken-mir-2.rs | 9 +++++++++ .../ui/const-generics/broken-mir-2.stderr | 19 +++++++++++++++++++ 4 files changed, 51 insertions(+) create mode 100644 src/test/ui/const-generics/broken-mir-1.rs create mode 100644 src/test/ui/const-generics/broken-mir-1.stderr create mode 100644 src/test/ui/const-generics/broken-mir-2.rs create mode 100644 src/test/ui/const-generics/broken-mir-2.stderr diff --git a/src/test/ui/const-generics/broken-mir-1.rs b/src/test/ui/const-generics/broken-mir-1.rs new file mode 100644 index 00000000000..9a11bd3d031 --- /dev/null +++ b/src/test/ui/const-generics/broken-mir-1.rs @@ -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 Foo for [T; N] { + fn foo(&self) { + let _ = &self; + } +} + +fn main() {} diff --git a/src/test/ui/const-generics/broken-mir-1.stderr b/src/test/ui/const-generics/broken-mir-1.stderr new file mode 100644 index 00000000000..55dc7fcb7cc --- /dev/null +++ b/src/test/ui/const-generics/broken-mir-1.stderr @@ -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)] + | ^^^^^^^^^^^^^^ + diff --git a/src/test/ui/const-generics/broken-mir-2.rs b/src/test/ui/const-generics/broken-mir-2.rs new file mode 100644 index 00000000000..2c93ed0defd --- /dev/null +++ b/src/test/ui/const-generics/broken-mir-2.rs @@ -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; N]); //~ ERROR `[T; N]` doesn't implement `std::fmt::Debug` + +fn main() {} diff --git a/src/test/ui/const-generics/broken-mir-2.stderr b/src/test/ui/const-generics/broken-mir-2.stderr new file mode 100644 index 00000000000..162153573a1 --- /dev/null +++ b/src/test/ui/const-generics/broken-mir-2.stderr @@ -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; N]` doesn't implement `std::fmt::Debug` + --> $DIR/broken-mir-2.rs:7:36 + | +LL | struct S([T; N]); + | ^^^^^^ `[T; N]` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `[T; N]` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `&[T; N]` + = 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`. From cfa1f80cd92c2fb273598adbb77e51ddbd3aef7b Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 21 May 2019 10:14:44 +0100 Subject: [PATCH 10/17] Fix test after rebase --- .../cannot-infer-type-for-const-param.rs | 1 + .../cannot-infer-type-for-const-param.stderr | 14 ++++++++++++-- 2 files changed, 13 insertions(+), 2 deletions(-) diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs index c3f5e360fe2..26496ec4a90 100644 --- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.rs @@ -8,4 +8,5 @@ struct Foo(pub [u8; NUM_BYTES]); fn main() { let _ = Foo::<3>([1, 2, 3]); //~ ERROR type annotations needed + //~^ ERROR mismatched types } diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr index a0641bd2fdc..1b5d9b173de 100644 --- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr @@ -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 `Const { ty: usize, val: Unevaluated(DefId(0:18 ~ cannot_infer_type_for_const_param[317d]::main[0]::{{constant}}[0]), []) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 3 }) }` + | + = 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`. From f865b7dda43cd8e453ec1ce485d9155e5591248f Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 25 May 2019 20:42:14 +0100 Subject: [PATCH 11/17] Update tests after pretty printing --- src/test/ui/const-generics/broken-mir-2.rs | 2 +- src/test/ui/const-generics/broken-mir-2.stderr | 8 ++++---- .../cannot-infer-type-for-const-param.stderr | 2 +- src/test/ui/consts/const-array-oob-arith.stderr | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/test/ui/const-generics/broken-mir-2.rs b/src/test/ui/const-generics/broken-mir-2.rs index 2c93ed0defd..fb9a63ea738 100644 --- a/src/test/ui/const-generics/broken-mir-2.rs +++ b/src/test/ui/const-generics/broken-mir-2.rs @@ -4,6 +4,6 @@ use std::fmt::Debug; #[derive(Debug)] -struct S([T; N]); //~ ERROR `[T; N]` doesn't implement `std::fmt::Debug` +struct S([T; N]); //~ ERROR `[T; _]` doesn't implement `std::fmt::Debug` fn main() {} diff --git a/src/test/ui/const-generics/broken-mir-2.stderr b/src/test/ui/const-generics/broken-mir-2.stderr index 162153573a1..fb9b88bde0a 100644 --- a/src/test/ui/const-generics/broken-mir-2.stderr +++ b/src/test/ui/const-generics/broken-mir-2.stderr @@ -4,14 +4,14 @@ warning: the feature `const_generics` is incomplete and may cause the compiler t LL | #![feature(const_generics)] | ^^^^^^^^^^^^^^ -error[E0277]: `[T; N]` doesn't implement `std::fmt::Debug` +error[E0277]: `[T; _]` doesn't implement `std::fmt::Debug` --> $DIR/broken-mir-2.rs:7:36 | LL | struct S([T; N]); - | ^^^^^^ `[T; N]` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | ^^^^^^ `[T; _]` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` | - = help: the trait `std::fmt::Debug` is not implemented for `[T; N]` - = note: required because of the requirements on the impl of `std::fmt::Debug` for `&[T; N]` + = 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 diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr index 1b5d9b173de..094bdbf486c 100644 --- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr @@ -14,7 +14,7 @@ error[E0308]: mismatched types --> $DIR/cannot-infer-type-for-const-param.rs:10:22 | LL | let _ = Foo::<3>([1, 2, 3]); - | ^^^^^^^^^ expected `Const { ty: usize, val: Unevaluated(DefId(0:18 ~ cannot_infer_type_for_const_param[317d]::main[0]::{{constant}}[0]), []) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 3 }) }` + | ^^^^^^^^^ expected `Const { ty: usize, val: Unevaluated(DefId(0:18 ~ cannot_infer_type_for_const_param[317d]::main[0]::{{constant}}[0]), []) }`, found `Const { ty: usize, val: Scalar(0x0000000000000003) }` | = note: expected type `[u8; _]` found type `[u8; 3]` diff --git a/src/test/ui/consts/const-array-oob-arith.stderr b/src/test/ui/consts/const-array-oob-arith.stderr index 29297b24e98..745d5904041 100644 --- a/src/test/ui/consts/const-array-oob-arith.stderr +++ b/src/test/ui/consts/const-array-oob-arith.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:7:45 | LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; - | ^^^ expected `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 2 }) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 1 }) }` + | ^^^ expected `Const { ty: usize, val: Scalar(0x0000000000000002) }`, found `Const { ty: usize, val: Scalar(0x0000000000000001) }` | = note: expected type `[i32; 2]` found type `[i32; 1]` @@ -11,7 +11,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:8:44 | LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99]; - | ^^^^^^^ expected `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 1 }) }`, found `Const { ty: usize, val: Scalar(Bits { size: 8, bits: 2 }) }` + | ^^^^^^^ expected `Const { ty: usize, val: Scalar(0x0000000000000001) }`, found `Const { ty: usize, val: Scalar(0x0000000000000002) }` | = note: expected type `[i32; 1]` found type `[i32; 2]` From f13317ca2ee16163ee121fbdf28eb2184840b6dd Mon Sep 17 00:00:00 2001 From: varkor Date: Sat, 25 May 2019 21:00:29 +0100 Subject: [PATCH 12/17] Use Display rather than Debug printing for const mismatch --- src/librustc/ty/error.rs | 2 +- .../const-generics/cannot-infer-type-for-const-param.stderr | 2 +- src/test/ui/consts/const-array-oob-arith.stderr | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 9bf1dbe2958..0a2a9472eaa 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -159,7 +159,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) } } } diff --git a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr index 094bdbf486c..fb151648f2f 100644 --- a/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr +++ b/src/test/ui/const-generics/cannot-infer-type-for-const-param.stderr @@ -14,7 +14,7 @@ error[E0308]: mismatched types --> $DIR/cannot-infer-type-for-const-param.rs:10:22 | LL | let _ = Foo::<3>([1, 2, 3]); - | ^^^^^^^^^ expected `Const { ty: usize, val: Unevaluated(DefId(0:18 ~ cannot_infer_type_for_const_param[317d]::main[0]::{{constant}}[0]), []) }`, found `Const { ty: usize, val: Scalar(0x0000000000000003) }` + | ^^^^^^^^^ expected `3`, found `3usize` | = note: expected type `[u8; _]` found type `[u8; 3]` diff --git a/src/test/ui/consts/const-array-oob-arith.stderr b/src/test/ui/consts/const-array-oob-arith.stderr index 745d5904041..ded8207cdef 100644 --- a/src/test/ui/consts/const-array-oob-arith.stderr +++ b/src/test/ui/consts/const-array-oob-arith.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:7:45 | LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; - | ^^^ expected `Const { ty: usize, val: Scalar(0x0000000000000002) }`, found `Const { ty: usize, val: Scalar(0x0000000000000001) }` + | ^^^ expected `2usize`, found `1usize` | = note: expected type `[i32; 2]` found type `[i32; 1]` @@ -11,7 +11,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:8:44 | LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99]; - | ^^^^^^^ expected `Const { ty: usize, val: Scalar(0x0000000000000001) }`, found `Const { ty: usize, val: Scalar(0x0000000000000002) }` + | ^^^^^^^ expected `1usize`, found `2usize` | = note: expected type `[i32; 1]` found type `[i32; 2]` From 854995313a029df89381449bb168bf61c88c546c Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 27 May 2019 14:05:29 +0100 Subject: [PATCH 13/17] Reintroduce `TypeError::FixedArraySize` --- src/librustc/ty/error.rs | 7 +++++++ src/librustc/ty/relate.rs | 18 ++++++++++++++++-- src/librustc/ty/structural_impls.rs | 2 ++ .../ui/consts/const-array-oob-arith.stderr | 4 ++-- 4 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 0a2a9472eaa..3d9e9cd6902 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -23,6 +23,7 @@ pub enum TypeError<'tcx> { AbiMismatch(ExpectedFound), Mutability, TupleSize(ExpectedFound), + FixedArraySize(ExpectedFound), ArgCount, RegionsDoesNotOutlive(Region<'tcx>, Region<'tcx>), @@ -99,6 +100,12 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { values.expected, values.found) } + FixedArraySize(values) => { + write!(f, "expected an array with a fixed size of {} elements, \ + found one with {} elements", + values.expected, + values.found) + } ArgCount => { write!(f, "incorrect number of function parameters") } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 55525d868e2..5a284e54396 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -472,8 +472,22 @@ 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 sz = relation.relate(&sz_a, &sz_b)?; - Ok(tcx.mk_ty(ty::Array(t, sz))) + 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 `usize`s, + // but differ in value, for better diagnostics. + // FIXME(eddyb) get the right param_env. + 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) + )) + } + _ => return Err(err), + } + } + } } (&ty::Slice(a_t), &ty::Slice(b_t)) => diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index b0062f20e7f..0daa567052d 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -716,6 +716,7 @@ impl<'a, 'tcx> Lift<'tcx> for ty::error::TypeError<'a> { AbiMismatch(x) => AbiMismatch(x), Mutability => Mutability, TupleSize(x) => TupleSize(x), + FixedArraySize(x) => FixedArraySize(x), ArgCount => ArgCount, RegionsDoesNotOutlive(a, b) => { return tcx.lift(&(a, b)).map(|(a, b)| RegionsDoesNotOutlive(a, b)) @@ -1294,6 +1295,7 @@ EnumTypeFoldableImpl! { (ty::error::TypeError::AbiMismatch)(x), (ty::error::TypeError::Mutability), (ty::error::TypeError::TupleSize)(x), + (ty::error::TypeError::FixedArraySize)(x), (ty::error::TypeError::ArgCount), (ty::error::TypeError::RegionsDoesNotOutlive)(a, b), (ty::error::TypeError::RegionsInsufficientlyPolymorphic)(a, b), diff --git a/src/test/ui/consts/const-array-oob-arith.stderr b/src/test/ui/consts/const-array-oob-arith.stderr index ded8207cdef..00286b0b0e0 100644 --- a/src/test/ui/consts/const-array-oob-arith.stderr +++ b/src/test/ui/consts/const-array-oob-arith.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:7:45 | LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; - | ^^^ expected `2usize`, found `1usize` + | ^^^ expected an array with a fixed size of 2 elements, found one with 1 elements | = note: expected type `[i32; 2]` found type `[i32; 1]` @@ -11,7 +11,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:8:44 | LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99]; - | ^^^^^^^ expected `1usize`, found `2usize` + | ^^^^^^^ expected an array with a fixed size of 1 elements, found one with 2 elements | = note: expected type `[i32; 1]` found type `[i32; 2]` From 56181cf8abf8ad7f7d36e92ef4d7bf294df23c4c Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 27 May 2019 14:28:20 +0100 Subject: [PATCH 14/17] Correct pluralisation of tuple/array/associated type binding mismatch errors --- src/librustc/ty/error.rs | 25 +++++++++++++------ .../ui/consts/const-array-oob-arith.stderr | 4 +-- src/test/ui/tuple/tuple-arity-mismatch.rs | 2 +- src/test/ui/tuple/tuple-arity-mismatch.stderr | 2 +- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/src/librustc/ty/error.rs b/src/librustc/ty/error.rs index 3d9e9cd6902..09426fe19e1 100644 --- a/src/librustc/ty/error.rs +++ b/src/librustc/ty/error.rs @@ -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"), @@ -95,16 +101,20 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { } Mutability => write!(f, "types differ in mutability"), 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 {} elements, \ - found one with {} elements", + write!(f, "expected an array with a fixed size of {} element{}, \ + found one with {} element{}", values.expected, - values.found) + 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) => { diff --git a/src/test/ui/consts/const-array-oob-arith.stderr b/src/test/ui/consts/const-array-oob-arith.stderr index 00286b0b0e0..77414fc7c92 100644 --- a/src/test/ui/consts/const-array-oob-arith.stderr +++ b/src/test/ui/consts/const-array-oob-arith.stderr @@ -2,7 +2,7 @@ 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]` @@ -11,7 +11,7 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:8: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]` diff --git a/src/test/ui/tuple/tuple-arity-mismatch.rs b/src/test/ui/tuple/tuple-arity-mismatch.rs index 1c8b881d246..4f505c05a6a 100644 --- a/src/test/ui/tuple/tuple-arity-mismatch.rs +++ b/src/test/ui/tuple/tuple-arity-mismatch.rs @@ -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 } diff --git a/src/test/ui/tuple/tuple-arity-mismatch.stderr b/src/test/ui/tuple/tuple-arity-mismatch.stderr index 650f4c58c77..6946a60c59a 100644 --- a/src/test/ui/tuple/tuple-arity-mismatch.stderr +++ b/src/test/ui/tuple/tuple-arity-mismatch.stderr @@ -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,)` From b3a13fdd13e11e11410e42a53f48c7d675f9963f Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 27 May 2019 14:30:16 +0100 Subject: [PATCH 15/17] Make sure array length diagnostic doesn't regress --- src/test/ui/consts/const-array-oob-arith.rs | 8 ++++++-- src/test/ui/consts/const-array-oob-arith.stderr | 2 +- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/src/test/ui/consts/const-array-oob-arith.rs b/src/test/ui/consts/const-array-oob-arith.rs index 2f9b30b51d1..2f5661e32a9 100644 --- a/src/test/ui/consts/const-array-oob-arith.rs +++ b/src/test/ui/consts/const-array-oob-arith.rs @@ -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; diff --git a/src/test/ui/consts/const-array-oob-arith.stderr b/src/test/ui/consts/const-array-oob-arith.stderr index 77414fc7c92..987e7ddf4d9 100644 --- a/src/test/ui/consts/const-array-oob-arith.stderr +++ b/src/test/ui/consts/const-array-oob-arith.stderr @@ -8,7 +8,7 @@ LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; 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 element, found one with 2 elements From 294916065a0692aa6b0c2c9e009da887cf897038 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 28 May 2019 20:25:21 +0100 Subject: [PATCH 16/17] Fix nits --- src/librustc/infer/resolve.rs | 4 ++-- src/librustc/ty/relate.rs | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/librustc/infer/resolve.rs b/src/librustc/infer/resolve.rs index 98f63c803ca..95bae8f2bd1 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -4,9 +4,9 @@ use crate::ty::{self, Ty, Const, TyCtxt, TypeFoldable, InferConst, TypeFlags}; use crate::ty::fold::{TypeFolder, TypeVisitor}; /////////////////////////////////////////////////////////////////////////// -// OPPORTUNISTIC KIND RESOLVER +// OPPORTUNISTIC VAR RESOLVER -/// The opportunistic kind resolver can be used at any time. It simply replaces +/// 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 diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 5a284e54396..0440be13a72 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -475,9 +475,8 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, 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 `usize`s, - // but differ in value, for better diagnostics. - // FIXME(eddyb) get the right param_env. + // 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( From 6233d1fee5df70258b02bb549967bc9319014081 Mon Sep 17 00:00:00 2001 From: varkor Date: Tue, 28 May 2019 21:34:18 +0100 Subject: [PATCH 17/17] Use assert_eq! instead of println! in tests --- .../ui/const-generics/uninferred-consts-during-codegen-1.rs | 2 +- .../ui/const-generics/uninferred-consts-during-codegen-2.rs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs index 2e555d11aba..1e064fbd970 100644 --- a/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-1.rs @@ -14,5 +14,5 @@ impl fmt::Debug for Array { } fn main() { - println!("{:?}", Array([1, 2, 3])); + assert_eq!(format!("{:?}", Array([1, 2, 3])), "[1, 2, 3]"); } diff --git a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs index 7a1a4f49794..0cf505906f6 100644 --- a/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs +++ b/src/test/ui/const-generics/uninferred-consts-during-codegen-2.rs @@ -14,5 +14,5 @@ impl fmt::Debug for Array<[T; N]> { } fn main() { - println!("{:?}", Array([1, 2, 3])); + assert_eq!(format!("{:?}", Array([1, 2, 3])), "[1, 2, 3]"); }