Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

The Genesis of Generic Germination #53645

Merged
merged 8 commits into from
May 6, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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
Member 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