diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 8ec9d42ec5f8..f87c6977f33d 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 ca159872ea7f..972ffbe1820a 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 60acbe0afe43..1dd391950254 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 5f5a2d4a489e..7461d8bc7286 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 b5a9184079aa..a4a7efdbc9e3 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 4351f94df2f1..220b7b5fa67f 100644 --- a/src/librustc/infer/opaque_types/mod.rs +++ b/src/librustc/infer/opaque_types/mod.rs @@ -286,7 +286,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; - let concrete_ty = self.resolve_type_vars_if_possible(&opaque_defn.concrete_ty); + let concrete_ty = self.resolve_vars_if_possible(&opaque_defn.concrete_ty); debug!("constrain_opaque_type: concrete_ty={:?}", concrete_ty); diff --git a/src/librustc/infer/outlives/env.rs b/src/librustc/infer/outlives/env.rs index 39aa51a95f79..3e626999200f 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 ee6603284851..90b3be213854 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 079385368f88..95bae8f2bd1a 100644 --- a/src/librustc/infer/resolve.rs +++ b/src/librustc/infer/resolve.rs @@ -1,28 +1,28 @@ use super::{InferCtxt, FixupError, FixupResult, Span, type_variable::TypeVariableOrigin}; use crate::mir::interpret::ConstValue; -use crate::ty::{self, Ty, TyCtxt, TypeFoldable, InferConst}; +use crate::ty::{self, Ty, Const, TyCtxt, TypeFoldable, InferConst, TypeFlags}; use crate::ty::fold::{TypeFolder, TypeVisitor}; /////////////////////////////////////////////////////////////////////////// -// OPPORTUNISTIC TYPE RESOLVER +// OPPORTUNISTIC VAR RESOLVER -/// The opportunistic type resolver can be used at any time. It simply replaces -/// type variables that have been unified with the things they have +/// The opportunistic resolver can be used at any time. It simply replaces +/// type/const variables that have been unified with the things they have /// been unified with (similar to `shallow_resolve`, but deep). This is /// useful for printing messages etc but also required at various /// points for correctness. -pub struct OpportunisticTypeResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { +pub struct OpportunisticVarResolver<'a, 'gcx: 'a+'tcx, 'tcx: 'a> { infcx: &'a InferCtxt<'a, 'gcx, 'tcx>, } -impl<'a, 'gcx, 'tcx> OpportunisticTypeResolver<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> OpportunisticVarResolver<'a, 'gcx, 'tcx> { #[inline] pub fn new(infcx: &'a InferCtxt<'a, 'gcx, 'tcx>) -> Self { - OpportunisticTypeResolver { infcx } + OpportunisticVarResolver { infcx } } } -impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'gcx, 'tcx> { +impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticVarResolver<'a, 'gcx, 'tcx> { fn tcx<'b>(&'b self) -> TyCtxt<'b, 'gcx, 'tcx> { self.infcx.tcx } @@ -31,8 +31,17 @@ impl<'a, 'gcx, 'tcx> TypeFolder<'gcx, 'tcx> for OpportunisticTypeResolver<'a, 'g if !t.has_infer_types() { t // micro-optimize -- if there is nothing in this type that this fold affects... } else { - let t0 = self.infcx.shallow_resolve(t); - t0.super_fold_with(self) + let t = self.infcx.shallow_resolve(t); + t.super_fold_with(self) + } + } + + fn fold_const(&mut self, ct: &'tcx Const<'tcx>) -> &'tcx Const<'tcx> { + if !ct.has_type_flags(TypeFlags::HAS_CT_INFER) { + ct // micro-optimize -- if there is nothing in this const that this fold affects... + } else { + let ct = self.infcx.shallow_resolve(ct); + ct.super_fold_with(self) } } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index c6b544469b5f..8d7c6f18a854 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 2fa896962daf..7505b3c1be84 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 d9eb6d8157df..a7b5e6cf41b7 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 7e3d6d752ccd..591557eb2bea 100644 --- a/src/librustc/traits/codegen/mod.rs +++ b/src/librustc/traits/codegen/mod.rs @@ -153,11 +153,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { bug!("Encountered errors `{:?}` resolving bounds after type-checking", errors); } - let result = self.resolve_type_vars_if_possible(result); + let result = self.resolve_vars_if_possible(result); let result = self.tcx.erase_regions(&result); self.tcx.lift_to_global(&result).unwrap_or_else(|| - bug!("Uninferred types/regions in `{:?}`", result) + bug!("Uninferred types/regions/consts in `{:?}`", result) ) } } diff --git a/src/librustc/traits/coherence.rs b/src/librustc/traits/coherence.rs index afbce5a4f0a4..c6521a931bb2 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 9019c4a0575d..5a2bf07b065f 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 96212d829d44..c7943d16885b 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 4b555e54f397..c135b0b759c6 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 92d5d4f03190..88bb3172c5e7 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 5800b024ad24..c4aa14d2b7eb 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 7e38282cc1ad..5933d2366e81 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 ec5e127a5ec4..ba96233b8532 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 5da4a1b9c5f3..b5d45d040fb9 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/ty/error.rs b/src/librustc/ty/error.rs index 4e4024d5bab4..09426fe19e11 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"), @@ -94,17 +100,21 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { values.found) } Mutability => write!(f, "types differ in mutability"), - FixedArraySize(values) => { - write!(f, "expected an array with a fixed size of {} elements, \ - found one with {} elements", + TupleSize(values) => { + write!(f, "expected a tuple with {} element{}, \ + found one with {} element{}", values.expected, - values.found) + pluralise!(values.expected), + values.found, + pluralise!(values.found)) } - TupleSize(values) => { - write!(f, "expected a tuple with {} elements, \ - found one with {} elements", + FixedArraySize(values) => { + 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) => { @@ -166,7 +177,7 @@ impl<'tcx> fmt::Display for TypeError<'tcx> { &format!("trait `{}`", values.found)) } ConstMismatch(ref values) => { - write!(f, "expected `{:?}`, found `{:?}`", values.expected, values.found) + write!(f, "expected `{}`, found `{}`", values.expected, values.found) } } } diff --git a/src/librustc/ty/relate.rs b/src/librustc/ty/relate.rs index 75d227d8067c..0440be13a727 100644 --- a/src/librustc/ty/relate.rs +++ b/src/librustc/ty/relate.rs @@ -8,9 +8,7 @@ use crate::hir::def_id::DefId; use crate::ty::subst::{Kind, UnpackedKind, SubstsRef}; use crate::ty::{self, Ty, TyCtxt, TypeFoldable}; use crate::ty::error::{ExpectedFound, TypeError}; -use crate::mir::interpret::{GlobalId, ConstValue, Scalar}; -use crate::util::common::ErrorReported; -use syntax_pos::DUMMY_SP; +use crate::mir::interpret::{ConstValue, Scalar, GlobalId}; use std::rc::Rc; use std::iter; use rustc_target::spec::abi; @@ -474,55 +472,19 @@ pub fn super_relate_tys<'a, 'gcx, 'tcx, R>(relation: &mut R, (&ty::Array(a_t, sz_a), &ty::Array(b_t, sz_b)) => { let t = relation.relate(&a_t, &b_t)?; - let to_u64 = |x: ty::Const<'tcx>| -> Result { - match x.val { - // FIXME(const_generics): this doesn't work right now, - // because it tries to relate an `Infer` to a `Param`. - ConstValue::Unevaluated(def_id, substs) => { - // FIXME(eddyb) get the right param_env. - let param_env = ty::ParamEnv::empty(); - if let Some(substs) = tcx.lift_to_global(&substs) { - let instance = ty::Instance::resolve( - tcx.global_tcx(), - param_env, - def_id, - substs, - ); - if let Some(instance) = instance { - let cid = GlobalId { - instance, - promoted: None, - }; - if let Some(s) = tcx.const_eval(param_env.and(cid)) - .ok() - .map(|c| c.unwrap_usize(tcx)) { - return Ok(s) - } - } + match relation.relate(&sz_a, &sz_b) { + Ok(sz) => Ok(tcx.mk_ty(ty::Array(t, sz))), + Err(err) => { + // Check whether the lengths are both concrete/known values, + // but are unequal, for better diagnostics. + match (sz_a.assert_usize(tcx), sz_b.assert_usize(tcx)) { + (Some(sz_a_val), Some(sz_b_val)) => { + Err(TypeError::FixedArraySize( + expected_found(relation, &sz_a_val, &sz_b_val) + )) } - tcx.sess.delay_span_bug(tcx.def_span(def_id), - "array length could not be evaluated"); - Err(ErrorReported) + _ => return Err(err), } - _ => x.assert_usize(tcx).ok_or_else(|| { - tcx.sess.delay_span_bug(DUMMY_SP, - "array length could not be evaluated"); - ErrorReported - }) - } - }; - match (to_u64(*sz_a), to_u64(*sz_b)) { - (Ok(sz_a_u64), Ok(sz_b_u64)) => { - if sz_a_u64 == sz_b_u64 { - Ok(tcx.mk_ty(ty::Array(t, sz_a))) - } else { - Err(TypeError::FixedArraySize( - expected_found(relation, &sz_a_u64, &sz_b_u64))) - } - } - // We reported an error or will ICE, so we can return Error. - (Err(ErrorReported), _) | (_, Err(ErrorReported)) => { - Ok(tcx.types.err) } } } @@ -598,11 +560,36 @@ where { let tcx = relation.tcx(); + let eagerly_eval = |x: &'tcx ty::Const<'tcx>| { + if let ConstValue::Unevaluated(def_id, substs) = x.val { + // FIXME(eddyb) get the right param_env. + let param_env = ty::ParamEnv::empty(); + if let Some(substs) = tcx.lift_to_global(&substs) { + let instance = ty::Instance::resolve( + tcx.global_tcx(), + param_env, + def_id, + substs, + ); + if let Some(instance) = instance { + let cid = GlobalId { + instance, + promoted: None, + }; + if let Ok(ct) = tcx.const_eval(param_env.and(cid)) { + return ct.val; + } + } + } + } + x.val + }; + // Currently, the values that can be unified are those that // implement both `PartialEq` and `Eq`, corresponding to // `structural_match` types. // FIXME(const_generics): check for `structural_match` synthetic attribute. - match (a.val, b.val) { + match (eagerly_eval(a), eagerly_eval(b)) { (ConstValue::Infer(_), _) | (_, ConstValue::Infer(_)) => { // The caller should handle these cases! bug!("var types encountered in super_relate_consts: {:?} {:?}", a, b) @@ -613,8 +600,13 @@ where (ConstValue::Placeholder(p1), ConstValue::Placeholder(p2)) if p1 == p2 => { Ok(a) } - (ConstValue::Scalar(Scalar::Raw { .. }), _) if a == b => { - Ok(a) + (a_val @ ConstValue::Scalar(Scalar::Raw { .. }), b_val @ _) + if a.ty == b.ty && a_val == b_val => + { + Ok(tcx.mk_const(ty::Const { + val: a_val, + ty: a.ty, + })) } (ConstValue::ByRef(..), _) => { bug!( @@ -635,9 +627,7 @@ where })) } - _ => { - Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))) - } + _ => Err(TypeError::ConstMismatch(expected_found(relation, &a, &b))), } } 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 de8e75ca277e..20b7f7eef0a1 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 04cd632b2979..96c647ca31e6 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 7ce450c7039a..c1f14cd3f8ed 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 9d234e93b837..f1b8588790b7 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 b1688a7fbbb7..73bb3fb5b9a2 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 412d2ca6dfcf..24fa5e97752a 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 a74a33b7448e..5a84e0cb85a6 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 f863cfe1887d..38c3ee776369 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 4689456d11fe..f8cad733ca1c 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 3fa192f16f32..419f61b0ee2c 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 90b2643d165b..d64be24f7538 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 08809917ba2b..3785c3c8684b 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 f93d5449e8b7..493486321ac2 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 65bc06b65e1f..213d53cf4825 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 596ce008099a..d78e01370827 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 dfe21edee41f..d2fcb987bc2d 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 f60ad5547a27..8701d751f2d9 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 cd207478f8f6..0bab63582aaa 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 353b9ac6cc30..62c9c7c8b1c3 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 13baf667808f..a856013b719f 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 diff --git a/src/test/ui/array-break-length.rs b/src/test/ui/array-break-length.rs index ab15ce6e8d8e..2696aea5e899 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 1cbf77a99f87..0e0dc8f623e6 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]` + +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 -For more information about this error, try `rustc --explain E0268`. +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 ac17bfdc941c..a7f16d70ba86 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 9b78aa16a580..46fbd3e0fae0 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]` + +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 -For more information about this error, try `rustc --explain E0268`. +Some errors have detailed explanations: E0268, E0308. +For more information about an error, try `rustc --explain E0268`. 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 000000000000..9a11bd3d0313 --- /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 000000000000..55dc7fcb7cc7 --- /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 000000000000..fb9a63ea738f --- /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; _]` 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 000000000000..fb9b88bde0a2 --- /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; _]` doesn't implement `std::fmt::Debug` + --> $DIR/broken-mir-2.rs:7:36 + | +LL | struct S([T; N]); + | ^^^^^^ `[T; _]` cannot be formatted using `{:?}` because it doesn't implement `std::fmt::Debug` + | + = help: the trait `std::fmt::Debug` is not implemented for `[T; _]` + = note: required because of the requirements on the impl of `std::fmt::Debug` for `&[T; _]` + = note: required for the cast to the object type `dyn std::fmt::Debug` + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0277`. 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 c3f5e360fe28..26496ec4a90b 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 a0641bd2fdc9..fb151648f2f9 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 `3`, found `3usize` + | + = note: expected type `[u8; _]` + found type `[u8; 3]` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0282`. +Some errors have detailed explanations: E0282, E0308. +For more information about an error, try `rustc --explain E0282`. 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 000000000000..d3d17cca4da2 --- /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 000000000000..367041283251 --- /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)] + | ^^^^^^^^^^^^^^ + 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 000000000000..1e064fbd9706 --- /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() { + assert_eq!(format!("{:?}", Array([1, 2, 3])), "[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 000000000000..eb2e446396c3 --- /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 000000000000..0cf505906f62 --- /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() { + assert_eq!(format!("{:?}", Array([1, 2, 3])), "[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 000000000000..eaa20bb78922 --- /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)] + | ^^^^^^^^^^^^^^ + diff --git a/src/test/ui/consts/const-array-oob-arith.rs b/src/test/ui/consts/const-array-oob-arith.rs index 2f9b30b51d10..2f5661e32a90 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 00286b0b0e0f..987e7ddf4d91 100644 --- a/src/test/ui/consts/const-array-oob-arith.stderr +++ b/src/test/ui/consts/const-array-oob-arith.stderr @@ -2,16 +2,16 @@ error[E0308]: mismatched types --> $DIR/const-array-oob-arith.rs:7:45 | LL | const BLUB: [i32; (ARR[0] - 40) as usize] = [5]; - | ^^^ expected an array with a fixed size of 2 elements, found one with 1 elements + | ^^^ expected an array with a fixed size of 2 elements, found one with 1 element | = note: expected type `[i32; 2]` found type `[i32; 1]` error[E0308]: mismatched types - --> $DIR/const-array-oob-arith.rs:8:44 + --> $DIR/const-array-oob-arith.rs:10:44 | LL | const BOO: [i32; (ARR[0] - 41) as usize] = [5, 99]; - | ^^^^^^^ expected an array with a fixed size of 1 elements, found one with 2 elements + | ^^^^^^^ expected an array with a fixed size of 1 element, found one with 2 elements | = note: expected type `[i32; 1]` found type `[i32; 2]` diff --git a/src/test/ui/tuple/tuple-arity-mismatch.rs b/src/test/ui/tuple/tuple-arity-mismatch.rs index 1c8b881d2469..4f505c05a6a2 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 650f4c58c776..6946a60c59af 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,)` 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 51bd116fbd61..5ad50ffcbc38 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 25cae8d9e495..851004d10589 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; _]` + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0080, E0435. +Some errors have detailed explanations: E0080, E0277, E0435. For more information about an error, try `rustc --explain E0080`.