Skip to content
15 changes: 15 additions & 0 deletions src/librustc/infer/at.rs
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@

use super::*;

use crate::ty::Const;
use crate::ty::relate::{Relate, TypeRelation};

pub struct At<'a, 'gcx: 'tcx, 'tcx: 'a> {
Expand Down Expand Up @@ -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,
Expand Down
10 changes: 6 additions & 4 deletions src/librustc/infer/canonical/query_response.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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());
}

_ => {
Expand Down Expand Up @@ -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,);
Expand Down
1 change: 1 addition & 0 deletions src/librustc/infer/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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),
}
Expand Down
2 changes: 2 additions & 0 deletions src/librustc/infer/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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>>),
}
Expand Down Expand Up @@ -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),
}
Expand Down
18 changes: 13 additions & 5 deletions src/librustc/ty/structural_impls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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),
Expand All @@ -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,
Expand All @@ -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
}
}
15 changes: 7 additions & 8 deletions src/librustc/ty/subst.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
40 changes: 26 additions & 14 deletions src/librustc_mir/monomorphize/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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"),
Expand Down Expand Up @@ -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.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This whole infrastructure should be rewritten to use ty::print, can you open an issue about that?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Opened #60582.

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);
Expand Down
2 changes: 0 additions & 2 deletions src/librustc_typeck/check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
4 changes: 1 addition & 3 deletions src/librustdoc/clean/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down
4 changes: 0 additions & 4 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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())?
Expand Down