diff options
| author | bors <bors@rust-lang.org> | 2019-05-06 16:43:25 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2019-05-06 16:43:25 +0000 |
| commit | a19cf18c7dbbcc46dddea81df3a4cee1735c2349 (patch) | |
| tree | 3acc8e9c4b9322ee50be98b4d9b245a30110b2c5 | |
| parent | c3b8ab5199af4a3c11d14b0cbdb17a641e8eee71 (diff) | |
| parent | 9a2772aff0e6c2058fb52a844b4593eabd18fcbc (diff) | |
| download | rust-a19cf18c7dbbcc46dddea81df3a4cee1735c2349.tar.gz rust-a19cf18c7dbbcc46dddea81df3a4cee1735c2349.zip | |
Auto merge of #53645 - varkor:const-generics-redux, r=eddyb
The Genesis of Generic Germination *Long had its coming been foretold: a collaborative effort with @yodaldevoid, set in motion by @jplatte, to beget a new Kind: one of a very different Sort to those that come before it. Amidst promises of ineffable powers previously thought unobtainable, few dared believe that the prophecies were true. But as they gazed upon that which claimed to be the Beginning, a few gentle sparks of hope fluttered deep within. It was not Time yet. But it was a Sign. And maybe, for some, that was enough.* There's a long way to go, but we're at the point where we would benefit from GitHub's reviewing capabilities. r? @eddyb
| -rw-r--r-- | src/librustc/infer/at.rs | 15 | ||||
| -rw-r--r-- | src/librustc/infer/canonical/query_response.rs | 10 | ||||
| -rw-r--r-- | src/librustc/infer/error_reporting/mod.rs | 1 | ||||
| -rw-r--r-- | src/librustc/infer/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustc/ty/structural_impls.rs | 18 | ||||
| -rw-r--r-- | src/librustc/ty/subst.rs | 15 | ||||
| -rw-r--r-- | src/librustc_mir/monomorphize/item.rs | 40 | ||||
| -rw-r--r-- | src/librustc_typeck/check/mod.rs | 2 | ||||
| -rw-r--r-- | src/librustdoc/clean/mod.rs | 4 | ||||
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 4 |
10 files changed, 71 insertions, 40 deletions
diff --git a/src/librustc/infer/at.rs b/src/librustc/infer/at.rs index 34cd3ae5427..57721108892 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/canonical/query_response.rs b/src/librustc/infer/canonical/query_response.rs index 8225ed70c58..413c1428ff9 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,); diff --git a/src/librustc/infer/error_reporting/mod.rs b/src/librustc/infer/error_reporting/mod.rs index 95b566d4a1b..4b6e7da3330 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 5846e604cfc..b5a9184079a 100644 --- a/src/librustc/infer/mod.rs +++ b/src/librustc/infer/mod.rs @@ -232,6 +232,7 @@ pub type PlaceholderMap<'tcx> = BTreeMap<ty::BoundRegion, ty::Region<'tcx>>; pub enum ValuePairs<'tcx> { Types(ExpectedFound<Ty<'tcx>>), Regions(ExpectedFound<ty::Region<'tcx>>), + Consts(ExpectedFound<&'tcx ty::Const<'tcx>>), TraitRefs(ExpectedFound<ty::TraitRef<'tcx>>), PolyTraitRefs(ExpectedFound<ty::PolyTraitRef<'tcx>>), } @@ -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), } diff --git a/src/librustc/ty/structural_impls.rs b/src/librustc/ty/structural_impls.rs index bab9527dd07..f81394a878f 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<V: TypeVisitor<'tcx>>(&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<V: TypeVisitor<'tcx>>(&self, _visitor: &mut V) -> bool { + false + } +} diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index 8d51fbc174a..e5bd3f15efe 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<T: TypeFoldable<'tcx>>(&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 diff --git a/src/librustc_mir/monomorphize/item.rs b/src/librustc_mir/monomorphize/item.rs index b001a09529e..999e7402afd 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); diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index e404a8e6972..82fcf8ff52f 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; } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index de74a6a5400..3a260db8065 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1706,9 +1706,7 @@ impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics, } Some(param.clean(cx)) } - ty::GenericParamDefKind::Const { .. } => { - unimplemented!() // FIXME(const_generics) - } + ty::GenericParamDefKind::Const { .. } => None, }).collect::<Vec<GenericParamDef>>(); let mut where_predicates = preds.predicates.iter() diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index d46feeab335..084091f4c2a 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())? |
