Skip to content

Commit

Permalink
Update term for use in more places
Browse files Browse the repository at this point in the history
Replace use of `ty()` on term and use it in more places. This will allow more flexibility in the
future, but slightly worried it allows items which are consts which only accept types.
  • Loading branch information
JulianKnodt committed Jan 17, 2022
1 parent 67f5667 commit e7529d6
Show file tree
Hide file tree
Showing 31 changed files with 284 additions and 128 deletions.
11 changes: 3 additions & 8 deletions compiler/rustc_infer/src/infer/opaque_types.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use rustc_hir as hir;
use rustc_hir::def_id::LocalDefId;
use rustc_middle::ty::fold::BottomUpFolder;
use rustc_middle::ty::subst::{GenericArgKind, Subst};
use rustc_middle::ty::{self, OpaqueTypeKey, Term, Ty, TyCtxt, TypeFoldable, TypeVisitor};
use rustc_middle::ty::{self, OpaqueTypeKey, Ty, TyCtxt, TypeFoldable, TypeVisitor};
use rustc_span::Span;

use std::ops::ControlFlow;
Expand Down Expand Up @@ -584,13 +584,8 @@ impl<'a, 'tcx> Instantiator<'a, 'tcx> {
debug!(?predicate);

if let ty::PredicateKind::Projection(projection) = predicate.kind().skip_binder() {
if let Term::Ty(ty) = projection.term {
if ty.references_error() {
// No point on adding these obligations since there's a type error involved.
return tcx.ty_error();
}
} else {
todo!();
if projection.term.references_error() {
return tcx.ty_error();
}
}

Expand Down
2 changes: 2 additions & 0 deletions compiler/rustc_interface/src/util.rs
Original file line number Diff line number Diff line change
Expand Up @@ -742,6 +742,8 @@ impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> {
ast::AssocConstraintKind::Equality { ref term } => {
match term {
Term::Ty(ty) => involves_impl_trait(ty),
// FIXME(...): This should check if the constant
// involves a trait impl, but for now ignore.
Term::Const(_) => false,
}
}
Expand Down
13 changes: 13 additions & 0 deletions compiler/rustc_middle/src/ty/assoc.rs
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,19 @@ impl<'tcx> AssocItems<'tcx> {
.find(|item| tcx.hygienic_eq(ident, item.ident, parent_def_id))
}

/// Returns the associated item with the given name and any of `AssocKind`, if one exists.
pub fn find_by_name_and_kinds(
&self,
tcx: TyCtxt<'_>,
ident: Ident,
kinds: &[AssocKind],
parent_def_id: DefId,
) -> Option<&ty::AssocItem> {
self.filter_by_name_unhygienic(ident.name)
.filter(|item| kinds.contains(&item.kind))
.find(|item| tcx.hygienic_eq(ident, item.ident, parent_def_id))
}

/// Returns the associated item with the given name in the given `Namespace`, if one exists.
pub fn find_by_name_and_namespace(
&self,
Expand Down
12 changes: 8 additions & 4 deletions compiler/rustc_middle/src/ty/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -86,10 +86,14 @@ impl<'tcx> Const<'tcx> {
if let Some(lit_input) = lit_input {
// If an error occurred, ignore that it's a literal and leave reporting the error up to
// mir.
if let Ok(c) = tcx.at(expr.span).lit_to_const(lit_input) {
return Some(c);
} else {
tcx.sess.delay_span_bug(expr.span, "Const::from_anon_const: couldn't lit_to_const");
match tcx.at(expr.span).lit_to_const(lit_input) {
Ok(c) => return Some(c),
Err(e) => {
tcx.sess.delay_span_bug(
expr.span,
&format!("Const::from_anon_const: couldn't lit_to_const {:?}", e),
);
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/flags.rs
Original file line number Diff line number Diff line change
Expand Up @@ -245,7 +245,7 @@ impl FlagComputation {
self.add_projection_ty(projection_ty);
match term {
Term::Ty(ty) => self.add_ty(ty),
Term::Const(_c) => todo!(),
Term::Const(c) => self.add_const(c),
}
}
ty::PredicateKind::WellFormed(arg) => {
Expand Down
8 changes: 4 additions & 4 deletions compiler/rustc_middle/src/ty/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -815,8 +815,8 @@ impl<'tcx> From<&'tcx Const<'tcx>> for Term<'tcx> {
}

impl<'tcx> Term<'tcx> {
pub fn ty(&self) -> Ty<'tcx> {
if let Term::Ty(ty) = self { ty } else { panic!("Expected type") }
pub fn ty(&self) -> Option<Ty<'tcx>> {
if let Term::Ty(ty) = self { Some(ty) } else { None }
}
}

Expand Down Expand Up @@ -861,8 +861,8 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx))
}

pub fn ty(&self) -> Binder<'tcx, Ty<'tcx>> {
self.map_bound(|predicate| if let Term::Ty(ty) = predicate.term { ty } else { todo!() })
pub fn term(&self) -> Binder<'tcx, Term<'tcx>> {
self.map_bound(|predicate| predicate.term)
}

/// The `DefId` of the `TraitItem` for the associated type.
Expand Down
24 changes: 15 additions & 9 deletions compiler/rustc_middle/src/ty/print/pretty.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::mir::interpret::{AllocRange, ConstValue, GlobalAlloc, Pointer, Provenance, Scalar};
use crate::ty::subst::{GenericArg, GenericArgKind, Subst};
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Ty, TyCtxt, TypeFoldable};
use crate::ty::{self, ConstInt, DefIdTree, ParamConst, ScalarInt, Term, Ty, TyCtxt, TypeFoldable};
use rustc_apfloat::ieee::{Double, Single};
use rustc_data_structures::fx::FxHashMap;
use rustc_data_structures::sso::SsoHashSet;
Expand Down Expand Up @@ -799,7 +799,7 @@ pub trait PrettyPrinter<'tcx>:
let trait_ref = proj_ref.required_poly_trait_ref(self.tcx());

// Projection type entry -- the def-id for naming, and the ty.
let proj_ty = (proj_ref.projection_def_id(), proj_ref.ty());
let proj_ty = (proj_ref.projection_def_id(), proj_ref.term());

self.insert_trait_and_projection(
trait_ref,
Expand Down Expand Up @@ -850,8 +850,10 @@ pub trait PrettyPrinter<'tcx>:
}

p!(")");
if !return_ty.skip_binder().is_unit() {
p!("-> ", print(return_ty));
if let Term::Ty(ty) = return_ty.skip_binder() {
if !ty.is_unit() {
p!("-> ", print(return_ty));
}
}
p!(write("{}", if paren_needed { ")" } else { "" }));

Expand Down Expand Up @@ -902,14 +904,15 @@ pub trait PrettyPrinter<'tcx>:
first = false;
}

for (assoc_item_def_id, ty) in assoc_items {
for (assoc_item_def_id, term) in assoc_items {
let ty = if let Term::Ty(ty) = term.skip_binder() { ty } else { continue };
if !first {
p!(", ");
}
p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).ident));

// Skip printing `<[generator@] as Generator<_>>::Return` from async blocks
match ty.skip_binder().kind() {
match ty.kind() {
ty::Projection(ty::ProjectionTy { item_def_id, .. })
if Some(*item_def_id) == self.tcx().lang_items().generator_return() =>
{
Expand Down Expand Up @@ -943,8 +946,11 @@ pub trait PrettyPrinter<'tcx>:
fn insert_trait_and_projection(
&mut self,
trait_ref: ty::PolyTraitRef<'tcx>,
proj_ty: Option<(DefId, ty::Binder<'tcx, Ty<'tcx>>)>,
traits: &mut BTreeMap<ty::PolyTraitRef<'tcx>, BTreeMap<DefId, ty::Binder<'tcx, Ty<'tcx>>>>,
proj_ty: Option<(DefId, ty::Binder<'tcx, Term<'tcx>>)>,
traits: &mut BTreeMap<
ty::PolyTraitRef<'tcx>,
BTreeMap<DefId, ty::Binder<'tcx, Term<'tcx>>>,
>,
fn_traits: &mut BTreeMap<ty::PolyTraitRef<'tcx>, OpaqueFnEntry<'tcx>>,
) {
let trait_def_id = trait_ref.def_id();
Expand Down Expand Up @@ -2716,5 +2722,5 @@ pub struct OpaqueFnEntry<'tcx> {
has_fn_once: bool,
fn_mut_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
fn_trait_ref: Option<ty::PolyTraitRef<'tcx>>,
return_ty: Option<ty::Binder<'tcx, Ty<'tcx>>>,
return_ty: Option<ty::Binder<'tcx, Term<'tcx>>>,
}
25 changes: 18 additions & 7 deletions compiler/rustc_middle/src/ty/relate.rs
Original file line number Diff line number Diff line change
Expand Up @@ -833,19 +833,30 @@ impl<'tcx> Relate<'tcx> for ty::TraitPredicate<'tcx> {
}
}

impl<'tcx> Relate<'tcx> for ty::Term<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: Self,
b: Self,
) -> RelateResult<'tcx, Self> {
Ok(match (a, b) {
(Term::Ty(a), Term::Ty(b)) => relation.relate(a, b)?.into(),
(Term::Const(a), Term::Const(b)) => relation.relate(a, b)?.into(),
_ => return Err(TypeError::Mismatch),
})
}
}

impl<'tcx> Relate<'tcx> for ty::ProjectionPredicate<'tcx> {
fn relate<R: TypeRelation<'tcx>>(
relation: &mut R,
a: ty::ProjectionPredicate<'tcx>,
b: ty::ProjectionPredicate<'tcx>,
) -> RelateResult<'tcx, ty::ProjectionPredicate<'tcx>> {
match (a.term, b.term) {
(Term::Ty(a_ty), Term::Ty(b_ty)) => Ok(ty::ProjectionPredicate {
projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
term: relation.relate(a_ty, b_ty)?.into(),
}),
_ => todo!(),
}
Ok(ty::ProjectionPredicate {
projection_ty: relation.relate(a.projection_ty, b.projection_ty)?,
term: relation.relate(a.term, b.term)?.into(),
})
}
}

Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_middle/src/ty/sty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1583,7 +1583,7 @@ impl<'tcx> ExistentialProjection<'tcx> {
let ty = if let Term::Ty(ty) = projection_predicate.term {
ty
} else {
todo!();
panic!("Only types are permitted here");
};

Self {
Expand Down
17 changes: 11 additions & 6 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,10 @@ where
polarity: _,
}) => self.visit_trait(trait_ref),
ty::PredicateKind::Projection(ty::ProjectionPredicate { projection_ty, term }) => {
let ty = term.ty();
ty.visit_with(self)?;
match term {
ty::Term::Ty(ty) => ty.visit_with(self)?,
ty::Term::Const(ct) => ct.visit_with(self)?,
}
self.visit_projection_ty(projection_ty)
}
ty::PredicateKind::TypeOutlives(ty::OutlivesPredicate(ty, _region)) => {
Expand Down Expand Up @@ -1186,10 +1188,13 @@ impl<'tcx> Visitor<'tcx> for TypePrivacyVisitor<'tcx> {
}

for (poly_predicate, _) in bounds.projection_bounds {
if self.visit(poly_predicate.skip_binder().term.ty()).is_break()
|| self
.visit_projection_ty(poly_predicate.skip_binder().projection_ty)
.is_break()
let pred = poly_predicate.skip_binder();
let poly_pred_term = match pred.term {
ty::Term::Ty(ty) => self.visit(ty),
ty::Term::Const(ct) => self.visit(ct),
};
if poly_pred_term.is_break()
|| self.visit_projection_ty(pred.projection_ty).is_break()
{
return;
}
Expand Down
16 changes: 11 additions & 5 deletions compiler/rustc_trait_selection/src/traits/auto_trait.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use super::*;
use crate::infer::region_constraints::{Constraint, RegionConstraintData};
use crate::infer::InferCtxt;
use rustc_middle::ty::fold::TypeFolder;
use rustc_middle::ty::{Region, RegionVid};
use rustc_middle::ty::{Region, RegionVid, Term};

use rustc_data_structures::fx::{FxHashMap, FxHashSet};

Expand Down Expand Up @@ -606,7 +606,11 @@ impl<'tcx> AutoTraitFinder<'tcx> {
}

fn is_self_referential_projection(&self, p: ty::PolyProjectionPredicate<'_>) -> bool {
matches!(*p.ty().skip_binder().kind(), ty::Projection(proj) if proj == p.skip_binder().projection_ty)
if let Term::Ty(ty) = p.term().skip_binder() {
matches!(ty.kind(), ty::Projection(proj) if proj == &p.skip_binder().projection_ty)
} else {
false
}
}

fn evaluate_nested_obligations(
Expand Down Expand Up @@ -663,7 +667,7 @@ impl<'tcx> AutoTraitFinder<'tcx> {
// Additionally, we check if we've seen this predicate before,
// to avoid rendering duplicate bounds to the user.
if self.is_param_no_infer(p.skip_binder().projection_ty.substs)
&& !p.ty().skip_binder().has_infer_types()
&& !p.term().skip_binder().has_infer_types()
&& is_new_pred
{
debug!(
Expand Down Expand Up @@ -752,7 +756,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
// when we started out trying to unify
// some inference variables. See the comment above
// for more infomration
if p.ty().skip_binder().has_infer_types() {
if p.term().skip_binder().ty().map_or(false, |ty| ty.has_infer_types())
{
if !self.evaluate_nested_obligations(
ty,
v.into_iter(),
Expand All @@ -774,7 +779,8 @@ impl<'tcx> AutoTraitFinder<'tcx> {
// However, we should always make progress (either by generating
// subobligations or getting an error) when we started off with
// inference variables
if p.ty().skip_binder().has_infer_types() {
if p.term().skip_binder().ty().map_or(false, |ty| ty.has_infer_types())
{
panic!("Unexpected result when selecting {:?} {:?}", ty, obligation)
}
}
Expand Down
10 changes: 5 additions & 5 deletions compiler/rustc_trait_selection/src/traits/error_reporting/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1304,8 +1304,7 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {

debug!(
"report_projection_error normalized_ty={:?} data.ty={:?}",
normalized_ty,
data.term.ty()
normalized_ty, data.term,
);

let is_normalized_ty_expected = !matches!(
Expand All @@ -1315,16 +1314,17 @@ impl<'a, 'tcx> InferCtxtPrivExt<'a, 'tcx> for InferCtxt<'a, 'tcx> {
| ObligationCauseCode::ObjectCastObligation(_)
| ObligationCauseCode::OpaqueType
);

// FIXME(...): Handle Consts here
let data_ty = data.term.ty().unwrap();
if let Err(error) = self.at(&obligation.cause, obligation.param_env).eq_exp(
is_normalized_ty_expected,
normalized_ty,
data.term.ty(),
data_ty,
) {
values = Some(infer::ValuePairs::Types(ExpectedFound::new(
is_normalized_ty_expected,
normalized_ty,
data.term.ty(),
data_ty,
)));

err_buf = error;
Expand Down
11 changes: 6 additions & 5 deletions compiler/rustc_trait_selection/src/traits/project.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,10 +212,9 @@ fn project_and_unify_type<'cx, 'tcx>(
debug!(?normalized_ty, ?obligations, "project_and_unify_type result");

let infcx = selcx.infcx();
match infcx
.at(&obligation.cause, obligation.param_env)
.eq(normalized_ty, obligation.predicate.term.ty())
{
// FIXME(...): Handle consts here as well as types.
let obligation_pred_ty = obligation.predicate.term.ty().unwrap();
match infcx.at(&obligation.cause, obligation.param_env).eq(normalized_ty, obligation_pred_ty) {
Ok(InferOk { obligations: inferred_obligations, value: () }) => {
obligations.extend(inferred_obligations);
Ok(Ok(Some(obligations)))
Expand Down Expand Up @@ -1803,7 +1802,9 @@ fn confirm_param_env_candidate<'cx, 'tcx>(
Ok(InferOk { value: _, obligations }) => {
nested_obligations.extend(obligations);
assoc_ty_own_obligations(selcx, obligation, &mut nested_obligations);
Progress { ty: cache_entry.term.ty(), obligations: nested_obligations }
// FIXME(...): Handle consts here as well? Maybe this progress type should just take
// a term instead.
Progress { ty: cache_entry.term.ty().unwrap(), obligations: nested_obligations }
}
Err(e) => {
let msg = format!(
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_trait_selection/src/traits/relationships.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ pub(crate) fn update<'tcx, T>(
if let ty::PredicateKind::Projection(predicate) = obligation.predicate.kind().skip_binder() {
// If the projection predicate (Foo::Bar == X) has X as a non-TyVid,
// we need to make it into one.
if let Some(vid) = predicate.term.ty().ty_vid() {
if let Some(vid) = predicate.term.ty().and_then(|ty| ty.ty_vid()) {
debug!("relationship: {:?}.output = true", vid);
engine.relationships().entry(vid).or_default().output = true;
}
Expand Down
7 changes: 5 additions & 2 deletions compiler/rustc_trait_selection/src/traits/wf.rs
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,10 @@ pub fn predicate_obligations<'a, 'tcx>(
}
ty::PredicateKind::Projection(t) => {
wf.compute_projection(t.projection_ty);
wf.compute(t.term.ty().into());
wf.compute(match t.term {
ty::Term::Ty(ty) => ty.into(),
ty::Term::Const(c) => c.into(),
})
}
ty::PredicateKind::WellFormed(arg) => {
wf.compute(arg);
Expand Down Expand Up @@ -219,7 +222,7 @@ fn extend_cause_with_original_assoc_item_obligation<'tcx>(
// projection coming from another associated type. See
// `src/test/ui/associated-types/point-at-type-on-obligation-failure.rs` and
// `traits-assoc-type-in-supertrait-bad.rs`.
if let ty::Projection(projection_ty) = proj.term.ty().kind() {
if let Some(ty::Projection(projection_ty)) = proj.term.ty().map(|ty| ty.kind()) {
if let Some(&impl_item_id) =
tcx.impl_item_implementor_ids(impl_def_id).get(&projection_ty.item_def_id)
{
Expand Down
Loading

0 comments on commit e7529d6

Please sign in to comment.