From 638d1d34ff89803b8558713fa6d5dff79019c854 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 6 May 2019 13:54:59 +0100 Subject: [PATCH 1/8] Remove duplicate comment Co-Authored-By: Gabriel Smith --- src/libsyntax/parse/parser.rs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d46feeab33599..084091f4c2a39 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6045,10 +6045,6 @@ impl<'a> Parser<'a> { }); assoc_ty_bindings.push(span); } else if self.check_const_arg() { - // FIXME(const_generics): to distinguish between idents for types and consts, - // we should introduce a GenericArg::Ident in the AST and distinguish when - // lowering to the HIR. For now, idents for const args are not permitted. - // Parse const argument. let expr = if let token::OpenDelim(token::Brace) = self.token { self.parse_block_expr(None, self.span, BlockCheckMode::Default, ThinVec::new())? From 59ebd1b7c2b9558ab31c57878666f0707f33b689 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 6 May 2019 13:55:14 +0100 Subject: [PATCH 2/8] Shift const vars through binders Co-Authored-By: Gabriel Smith --- src/librustc/ty/subst.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 8d51fbc174a04..e5bd3f15efe95 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -618,8 +618,7 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> { } }; - // FIXME(const_generics): shift const through binders - ct + self.shift_vars_through_binders(ct) } /// It is sometimes necessary to adjust the De Bruijn indices during substitution. This occurs @@ -664,15 +663,15 @@ impl<'a, 'gcx, 'tcx> SubstFolder<'a, 'gcx, 'tcx> { /// As indicated in the diagram, here the same type `&'a int` is substituted once, but in the /// first case we do not increase the De Bruijn index and in the second case we do. The reason /// is that only in the second case have we passed through a fn binder. - fn shift_vars_through_binders(&self, ty: Ty<'tcx>) -> Ty<'tcx> { - debug!("shift_vars(ty={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})", - ty, self.binders_passed, ty.has_escaping_bound_vars()); + fn shift_vars_through_binders>(&self, val: T) -> T { + debug!("shift_vars(val={:?}, binders_passed={:?}, has_escaping_bound_vars={:?})", + val, self.binders_passed, val.has_escaping_bound_vars()); - if self.binders_passed == 0 || !ty.has_escaping_bound_vars() { - return ty; + if self.binders_passed == 0 || !val.has_escaping_bound_vars() { + return val; } - let result = ty::fold::shift_vars(self.tcx(), &ty, self.binders_passed); + let result = ty::fold::shift_vars(self.tcx(), &val, self.binders_passed); debug!("shift_vars: shifted result = {:?}", result); result From ad78fcf5246c9accb2a35ced91d85b710648abc9 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 6 May 2019 13:55:28 +0100 Subject: [PATCH 3/8] Ignore const parameters when constructing type bounds in rustdoc Co-Authored-By: Gabriel Smith --- src/librustdoc/clean/mod.rs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index de74a6a540055..3a260db806520 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1706,9 +1706,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, } Some(param.clean(cx)) } - ty::GenericParamDefKind::Const { .. } => { - unimplemented!() // FIXME(const_generics) - } + ty::GenericParamDefKind::Const { .. } => None, }).collect::>(); let mut where_predicates = preds.predicates.iter() From c6197541f73c570f5104c36920b387992c7658d2 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 6 May 2019 14:05:26 +0100 Subject: [PATCH 4/8] Implement TypeFoldable for InferConst Co-Authored-By: Gabriel Smith --- src/librustc/ty/structural_impls.rs | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index bab9527dd07f6..f81394a878f5a 100644 --- a/src/librustc/ty/structural_impls.rs +++ b/src/librustc/ty/structural_impls.rs @@ -6,7 +6,7 @@ use crate::hir::def::Namespace; use crate::mir::ProjectionKind; use crate::mir::interpret::ConstValue; -use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid}; +use crate::ty::{self, Lift, Ty, TyCtxt, ConstVid, InferConst}; use crate::ty::fold::{TypeFoldable, TypeFolder, TypeVisitor}; use crate::ty::print::{FmtPrinter, Printer}; use rustc_data_structures::indexed_vec::{IndexVec, Idx}; @@ -1352,8 +1352,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, folder: &mut F) -> Self { match *self { ConstValue::ByRef(ptr, alloc) => ConstValue::ByRef(ptr, alloc), - // FIXME(const_generics): implement TypeFoldable for InferConst - ConstValue::Infer(ic) => ConstValue::Infer(ic), + ConstValue::Infer(ic) => ConstValue::Infer(ic.fold_with(folder)), ConstValue::Param(p) => ConstValue::Param(p.fold_with(folder)), ConstValue::Placeholder(p) => ConstValue::Placeholder(p), ConstValue::Scalar(a) => ConstValue::Scalar(a), @@ -1366,8 +1365,7 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { fn super_visit_with>(&self, visitor: &mut V) -> bool { match *self { ConstValue::ByRef(..) => false, - // FIXME(const_generics): implement TypeFoldable for InferConst - ConstValue::Infer(_) => false, + ConstValue::Infer(ic) => ic.visit_with(visitor), ConstValue::Param(p) => p.visit_with(visitor), ConstValue::Placeholder(_) => false, ConstValue::Scalar(_) => false, @@ -1376,3 +1374,13 @@ impl<'tcx> TypeFoldable<'tcx> for ConstValue<'tcx> { } } } + +impl<'tcx> TypeFoldable<'tcx> for InferConst<'tcx> { + fn super_fold_with<'gcx: 'tcx, F: TypeFolder<'gcx, 'tcx>>(&self, _folder: &mut F) -> Self { + *self + } + + fn super_visit_with>(&self, _visitor: &mut V) -> bool { + false + } +} From 670cf11de22583e1192636f0e6c36007ebcbb776 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 6 May 2019 14:16:07 +0100 Subject: [PATCH 5/8] Clean up `push_const_name` Co-Authored-By: Gabriel Smith --- src/librustc_mir/monomorphize/item.rs | 40 +++++++++++++++++---------- 1 file changed, 26 insertions(+), 14 deletions(-) diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index b001a09529e5b..999e7402afd93 100644 --- a/src/librustc_mir/monomorphize/item.rs +++ b/src/librustc_mir/monomorphize/item.rs @@ -3,7 +3,7 @@ use rustc::hir; use rustc::hir::def_id::{DefId, LOCAL_CRATE}; use rustc::mir::interpret::ConstValue; use rustc::session::config::OptLevel; -use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts, ParamConst}; +use rustc::ty::{self, Ty, TyCtxt, Const, ClosureSubsts, GeneratorSubsts}; use rustc::ty::subst::{SubstsRef, InternalSubsts}; use syntax::ast; use syntax::attr::InlineAttr; @@ -240,11 +240,11 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { } // Pushes the type name of the specified type to the provided string. - // If 'debug' is true, printing normally unprintable types is allowed - // (e.g. ty::GeneratorWitness). This parameter should only be set when - // this method is being used for logging purposes (e.g. with debug! or info!) - // When being used for codegen purposes, 'debug' should be set to 'false' - // in order to catch unexpected types that should never end up in a type name + // If `debug` is true, printing normally unprintable types is allowed + // (e.g. `ty::GeneratorWitness`). This parameter should only be set when + // this method is being used for logging purposes (e.g. with `debug!` or `info!`) + // When being used for codegen purposes, `debug` should be set to `false` + // in order to catch unexpected types that should never end up in a type name. pub fn push_type_name(&self, t: Ty<'tcx>, output: &mut String, debug: bool) { match t.sty { ty::Bool => output.push_str("bool"), @@ -387,22 +387,34 @@ impl<'a, 'tcx> DefPathBasedNames<'a, 'tcx> { if debug { output.push_str(&format!("`{:?}`", t)); } else { - bug!("DefPathBasedNames: Trying to create type name for \ - unexpected type: {:?}", t); + bug!( + "DefPathBasedNames: trying to create type name for unexpected type: {:?}", + t, + ); } } } } - // FIXME(const_generics): handle debug printing. + // Pushes the the name of the specified const to the provided string. + // If `debug` is true, usually-unprintable consts (such as `Infer`) will be printed, + // as well as the unprintable types of constants (see `push_type_name` for more details). pub fn push_const_name(&self, c: &Const<'tcx>, output: &mut String, debug: bool) { match c.val { - ConstValue::Infer(..) | ConstValue::Placeholder(_) => output.push_str("_"), - ConstValue::Param(ParamConst { name, .. }) => { - write!(output, "{}", name).unwrap(); + ConstValue::Scalar(..) | ConstValue::Slice(..) | ConstValue::ByRef(..) => { + // FIXME(const_generics): we could probably do a better job here. + write!(output, "{:?}", c).unwrap() + } + _ => { + if debug { + write!(output, "{:?}", c).unwrap() + } else { + bug!( + "DefPathBasedNames: trying to create const name for unexpected const: {:?}", + c, + ); + } } - ConstValue::Unevaluated(..) => output.push_str("_: _"), - _ => write!(output, "{:?}", c).unwrap(), } output.push_str(": "); self.push_type_name(c.ty, output, debug); From c0454f0638f235dd7c8b4bb57ea5614e5e877746 Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 6 May 2019 14:16:28 +0100 Subject: [PATCH 6/8] Remove incorrect FIXME Co-Authored-By: Gabriel Smith --- src/librustc_typeck/check/mod.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e404a8e6972c8..82fcf8ff52f83 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5785,8 +5785,6 @@ pub fn check_bounds_are_used<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, ty ); - // FIXME(const_generics): we probably want to check the bounds for const parameters too. - if own_counts.types == 0 { return; } From 5fc0395053c732c8becf0e1dca7000554c352ccd Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 6 May 2019 14:17:48 +0100 Subject: [PATCH 7/8] Resolve a couple of `unimplemented!()`s Co-Authored-By: Gabriel Smith --- src/librustc/infer/canonical/query_response.rs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/librustc/infer/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 8225ed70c5827..413c1428ff954 100644 --- a/src/librustc/infer/canonical/query_response.rs +++ b/src/librustc/infer/canonical/query_response.rs @@ -318,8 +318,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { obligations.extend(ok.into_obligations()); } - (UnpackedKind::Const(..), UnpackedKind::Const(..)) => { - unimplemented!() // FIXME(const_generics) + (UnpackedKind::Const(v1), UnpackedKind::Const(v2)) => { + let ok = self.at(cause, param_env).eq(v1, v2)?; + obligations.extend(ok.into_obligations()); } _ => { @@ -626,8 +627,9 @@ impl<'cx, 'gcx, 'tcx> InferCtxt<'cx, 'gcx, 'tcx> { obligations .extend(self.at(cause, param_env).eq(v1, v2)?.into_obligations()); } - (UnpackedKind::Const(..), UnpackedKind::Const(..)) => { - unimplemented!() // FIXME(const_generics) + (UnpackedKind::Const(v1), UnpackedKind::Const(v2)) => { + let ok = self.at(cause, param_env).eq(v1, v2)?; + obligations.extend(ok.into_obligations()); } _ => { bug!("kind mismatch, cannot unify {:?} and {:?}", value1, value2,); From 9a2772aff0e6c2058fb52a844b4593eabd18fcbc Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 6 May 2019 15:07:46 +0100 Subject: [PATCH 8/8] Implement `ToTrace` for `ty::Const` --- src/librustc/infer/at.rs | 15 +++++++++++++++ src/librustc/infer/error_reporting/mod.rs | 1 + src/librustc/infer/mod.rs | 2 ++ 3 files changed, 18 insertions(+) diff --git a/src/librustc/infer/at.rs b/src/librustc/infer/at.rs index 34cd3ae5427e0..5772110889290 100644 --- a/src/librustc/infer/at.rs +++ b/src/librustc/infer/at.rs @@ -27,6 +27,7 @@ use super::*; +use crate::ty::Const; use crate::ty::relate::{Relate, TypeRelation}; pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> { @@ -308,6 +309,20 @@ impl<'tcx> ToTrace<'tcx> for ty::Region<'tcx> { } } +impl<'tcx> ToTrace<'tcx> for &'tcx Const<'tcx> { + fn to_trace(cause: &ObligationCause<'tcx>, + a_is_expected: bool, + a: Self, + b: Self) + -> TypeTrace<'tcx> + { + TypeTrace { + cause: cause.clone(), + values: Consts(ExpectedFound::new(a_is_expected, a, b)) + } + } +} + impl<'tcx> ToTrace<'tcx> for ty::TraitRef<'tcx> { fn to_trace(cause: &ObligationCause<'tcx>, a_is_expected: bool, diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 95b566d4a1b69..4b6e7da333081 100644 --- a/src/librustc/infer/error_reporting/mod.rs +++ b/src/librustc/infer/error_reporting/mod.rs @@ -1260,6 +1260,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { match *values { infer::Types(ref exp_found) => self.expected_found_str_ty(exp_found), infer::Regions(ref exp_found) => self.expected_found_str(exp_found), + infer::Consts(ref exp_found) => self.expected_found_str(exp_found), infer::TraitRefs(ref exp_found) => self.expected_found_str(exp_found), infer::PolyTraitRefs(ref exp_found) => self.expected_found_str(exp_found), } diff --git a/src/librustc/infer/mod.rs b/src/librustc/infer/mod.rs index 5846e604cfc09..b5a9184079aa6 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -232,6 +232,7 @@ pub type PlaceholderMap<'tcx> = BTreeMap>; pub enum ValuePairs<'tcx> { Types(ExpectedFound>), Regions(ExpectedFound>), + Consts(ExpectedFound<&'tcx ty::Const<'tcx>>), TraitRefs(ExpectedFound>), PolyTraitRefs(ExpectedFound>), } @@ -1730,6 +1731,7 @@ EnumTypeFoldableImpl! { impl<'tcx> TypeFoldable<'tcx> for ValuePairs<'tcx> { (ValuePairs::Types)(a), (ValuePairs::Regions)(a), + (ValuePairs::Consts)(a), (ValuePairs::TraitRefs)(a), (ValuePairs::PolyTraitRefs)(a), }