banish hir::GenericBound::LangItemTrait
This commit is contained in:
parent
ad00641b74
commit
fc010de26b
12 changed files with 68 additions and 135 deletions
|
@ -766,6 +766,28 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.resolver.get_import_res(id).present_items()
|
self.resolver.get_import_res(id).present_items()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn make_lang_item_path(
|
||||||
|
&mut self,
|
||||||
|
lang_item: hir::LangItem,
|
||||||
|
span: Span,
|
||||||
|
args: Option<&'hir hir::GenericArgs<'hir>>,
|
||||||
|
) -> &'hir hir::Path<'hir> {
|
||||||
|
let def_id = self.tcx.require_lang_item(lang_item, Some(span));
|
||||||
|
let def_kind = self.tcx.def_kind(def_id);
|
||||||
|
let res = Res::Def(def_kind, def_id);
|
||||||
|
self.arena.alloc(hir::Path {
|
||||||
|
span,
|
||||||
|
res,
|
||||||
|
segments: self.arena.alloc_from_iter([hir::PathSegment {
|
||||||
|
ident: Ident::new(lang_item.name(), span),
|
||||||
|
hir_id: self.next_id(),
|
||||||
|
res,
|
||||||
|
args,
|
||||||
|
infer_args: false,
|
||||||
|
}]),
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
/// Reuses the span but adds information like the kind of the desugaring and features that are
|
/// Reuses the span but adds information like the kind of the desugaring and features that are
|
||||||
/// allowed inside this span.
|
/// allowed inside this span.
|
||||||
fn mark_span_with_reason(
|
fn mark_span_with_reason(
|
||||||
|
@ -1977,18 +1999,27 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
|
CoroutineKind::AsyncGen { .. } => (sym::Item, hir::LangItem::AsyncIterator),
|
||||||
};
|
};
|
||||||
|
|
||||||
let future_args = self.arena.alloc(hir::GenericArgs {
|
let bound_args = self.arena.alloc(hir::GenericArgs {
|
||||||
args: &[],
|
args: &[],
|
||||||
bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
|
bindings: arena_vec![self; self.assoc_ty_binding(assoc_ty_name, opaque_ty_span, output_ty)],
|
||||||
parenthesized: hir::GenericArgsParentheses::No,
|
parenthesized: hir::GenericArgsParentheses::No,
|
||||||
span_ext: DUMMY_SP,
|
span_ext: DUMMY_SP,
|
||||||
});
|
});
|
||||||
|
|
||||||
hir::GenericBound::LangItemTrait(
|
hir::GenericBound::Trait(
|
||||||
|
hir::PolyTraitRef {
|
||||||
|
bound_generic_params: &[],
|
||||||
|
trait_ref: hir::TraitRef {
|
||||||
|
path: self.make_lang_item_path(
|
||||||
trait_lang_item,
|
trait_lang_item,
|
||||||
opaque_ty_span,
|
opaque_ty_span,
|
||||||
self.next_id(),
|
Some(bound_args),
|
||||||
future_args,
|
),
|
||||||
|
hir_ref_id: self.next_id(),
|
||||||
|
},
|
||||||
|
span: opaque_ty_span,
|
||||||
|
},
|
||||||
|
hir::TraitBoundModifier::None,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -788,28 +788,18 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
|
||||||
};
|
};
|
||||||
let opaque_ty = hir.item(id);
|
let opaque_ty = hir.item(id);
|
||||||
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
if let hir::ItemKind::OpaqueTy(hir::OpaqueTy {
|
||||||
bounds:
|
bounds: [hir::GenericBound::Trait(trait_ref, _)],
|
||||||
[
|
|
||||||
hir::GenericBound::LangItemTrait(
|
|
||||||
hir::LangItem::Future,
|
|
||||||
_,
|
|
||||||
_,
|
|
||||||
hir::GenericArgs {
|
|
||||||
bindings:
|
|
||||||
[
|
|
||||||
hir::TypeBinding {
|
|
||||||
ident: Ident { name: sym::Output, .. },
|
|
||||||
kind:
|
|
||||||
hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
|
|
||||||
..
|
|
||||||
},
|
|
||||||
],
|
|
||||||
..
|
|
||||||
},
|
|
||||||
),
|
|
||||||
],
|
|
||||||
..
|
..
|
||||||
}) = opaque_ty.kind
|
}) = opaque_ty.kind
|
||||||
|
&& let Some(segment) = trait_ref.trait_ref.path.segments.last()
|
||||||
|
&& let Some(args) = segment.args
|
||||||
|
&& let [
|
||||||
|
hir::TypeBinding {
|
||||||
|
ident: Ident { name: sym::Output, .. },
|
||||||
|
kind: hir::TypeBindingKind::Equality { term: hir::Term::Ty(ty) },
|
||||||
|
..
|
||||||
|
},
|
||||||
|
] = args.bindings
|
||||||
{
|
{
|
||||||
ty
|
ty
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -435,8 +435,6 @@ pub enum TraitBoundModifier {
|
||||||
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
#[derive(Clone, Copy, Debug, HashStable_Generic)]
|
||||||
pub enum GenericBound<'hir> {
|
pub enum GenericBound<'hir> {
|
||||||
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
Trait(PolyTraitRef<'hir>, TraitBoundModifier),
|
||||||
// FIXME(davidtwco): Introduce `PolyTraitRef::LangItem`
|
|
||||||
LangItemTrait(LangItem, Span, HirId, &'hir GenericArgs<'hir>),
|
|
||||||
Outlives(&'hir Lifetime),
|
Outlives(&'hir Lifetime),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -451,7 +449,6 @@ impl GenericBound<'_> {
|
||||||
pub fn span(&self) -> Span {
|
pub fn span(&self) -> Span {
|
||||||
match self {
|
match self {
|
||||||
GenericBound::Trait(t, ..) => t.span,
|
GenericBound::Trait(t, ..) => t.span,
|
||||||
GenericBound::LangItemTrait(_, span, ..) => *span,
|
|
||||||
GenericBound::Outlives(l) => l.ident.span,
|
GenericBound::Outlives(l) => l.ident.span,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1075,10 +1075,6 @@ pub fn walk_param_bound<'v, V: Visitor<'v>>(visitor: &mut V, bound: &'v GenericB
|
||||||
GenericBound::Trait(ref typ, _modifier) => {
|
GenericBound::Trait(ref typ, _modifier) => {
|
||||||
visitor.visit_poly_trait_ref(typ);
|
visitor.visit_poly_trait_ref(typ);
|
||||||
}
|
}
|
||||||
GenericBound::LangItemTrait(_, _span, hir_id, args) => {
|
|
||||||
visitor.visit_id(hir_id);
|
|
||||||
visitor.visit_generic_args(args);
|
|
||||||
}
|
|
||||||
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
|
GenericBound::Outlives(ref lifetime) => visitor.visit_lifetime(lifetime),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -134,17 +134,6 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
|
||||||
only_self_bounds,
|
only_self_bounds,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
&hir::GenericBound::LangItemTrait(lang_item, span, hir_id, args) => {
|
|
||||||
self.instantiate_lang_item_trait_ref(
|
|
||||||
lang_item,
|
|
||||||
span,
|
|
||||||
hir_id,
|
|
||||||
args,
|
|
||||||
param_ty,
|
|
||||||
bounds,
|
|
||||||
only_self_bounds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
hir::GenericBound::Outlives(lifetime) => {
|
hir::GenericBound::Outlives(lifetime) => {
|
||||||
let region = self.ast_region_to_region(lifetime, None);
|
let region = self.ast_region_to_region(lifetime, None);
|
||||||
bounds.push_region_bound(
|
bounds.push_region_bound(
|
||||||
|
|
|
@ -791,6 +791,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
|
self.prohibit_generics(trait_ref.path.segments.split_last().unwrap().1.iter(), |_| {});
|
||||||
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
|
self.complain_about_internal_fn_trait(span, trait_def_id, trait_segment, false);
|
||||||
|
|
||||||
|
// TODO: inline
|
||||||
self.instantiate_poly_trait_ref_inner(
|
self.instantiate_poly_trait_ref_inner(
|
||||||
hir_id,
|
hir_id,
|
||||||
span,
|
span,
|
||||||
|
@ -809,42 +810,6 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn instantiate_lang_item_trait_ref(
|
|
||||||
&self,
|
|
||||||
lang_item: hir::LangItem,
|
|
||||||
span: Span,
|
|
||||||
hir_id: hir::HirId,
|
|
||||||
args: &GenericArgs<'_>,
|
|
||||||
self_ty: Ty<'tcx>,
|
|
||||||
bounds: &mut Bounds<'tcx>,
|
|
||||||
only_self_bounds: OnlySelfBounds,
|
|
||||||
) {
|
|
||||||
let binding_span = Some(span);
|
|
||||||
let constness = ty::BoundConstness::NotConst;
|
|
||||||
let speculative = false;
|
|
||||||
let trait_ref_span = span;
|
|
||||||
let trait_def_id = self.tcx().require_lang_item(lang_item, Some(span));
|
|
||||||
let trait_segment = &hir::PathSegment::invalid();
|
|
||||||
let infer_args = false;
|
|
||||||
|
|
||||||
self.instantiate_poly_trait_ref_inner(
|
|
||||||
hir_id,
|
|
||||||
span,
|
|
||||||
binding_span,
|
|
||||||
constness,
|
|
||||||
ty::ImplPolarity::Positive,
|
|
||||||
bounds,
|
|
||||||
speculative,
|
|
||||||
trait_ref_span,
|
|
||||||
trait_def_id,
|
|
||||||
trait_segment,
|
|
||||||
args,
|
|
||||||
infer_args,
|
|
||||||
self_ty,
|
|
||||||
only_self_bounds,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
fn ast_path_to_mono_trait_ref(
|
fn ast_path_to_mono_trait_ref(
|
||||||
&self,
|
&self,
|
||||||
span: Span,
|
span: Span,
|
||||||
|
|
|
@ -938,32 +938,6 @@ impl<'a, 'tcx> Visitor<'tcx> for BoundVarContext<'a, 'tcx> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_param_bound(&mut self, bound: &'tcx hir::GenericBound<'tcx>) {
|
|
||||||
match bound {
|
|
||||||
hir::GenericBound::LangItemTrait(_, _, hir_id, _) => {
|
|
||||||
// FIXME(jackh726): This is pretty weird. `LangItemTrait` doesn't go
|
|
||||||
// through the regular poly trait ref code, so we don't get another
|
|
||||||
// chance to introduce a binder. For now, I'm keeping the existing logic
|
|
||||||
// of "if there isn't a Binder scope above us, add one", but I
|
|
||||||
// imagine there's a better way to go about this.
|
|
||||||
let (binders, scope_type) = self.poly_trait_ref_binder_info();
|
|
||||||
|
|
||||||
self.record_late_bound_vars(*hir_id, binders);
|
|
||||||
let scope = Scope::Binder {
|
|
||||||
hir_id: *hir_id,
|
|
||||||
bound_vars: FxIndexMap::default(),
|
|
||||||
s: self.scope,
|
|
||||||
scope_type,
|
|
||||||
where_bound_origin: None,
|
|
||||||
};
|
|
||||||
self.with(scope, |this| {
|
|
||||||
intravisit::walk_param_bound(this, bound);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
_ => intravisit::walk_param_bound(self, bound),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
|
fn visit_poly_trait_ref(&mut self, trait_ref: &'tcx hir::PolyTraitRef<'tcx>) {
|
||||||
self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow);
|
self.visit_poly_trait_ref_inner(trait_ref, NonLifetimeBinderAllowed::Allow);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2088,11 +2088,6 @@ impl<'a> State<'a> {
|
||||||
}
|
}
|
||||||
self.print_poly_trait_ref(tref);
|
self.print_poly_trait_ref(tref);
|
||||||
}
|
}
|
||||||
GenericBound::LangItemTrait(lang_item, span, ..) => {
|
|
||||||
self.word("#[lang = \"");
|
|
||||||
self.print_ident(Ident::new(lang_item.name(), *span));
|
|
||||||
self.word("\"]");
|
|
||||||
}
|
|
||||||
GenericBound::Outlives(lt) => {
|
GenericBound::Outlives(lt) => {
|
||||||
self.print_lifetime(lt);
|
self.print_lifetime(lt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -825,9 +825,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||||
&& let hir::Node::Item(hir::Item {
|
&& let hir::Node::Item(hir::Item {
|
||||||
kind: hir::ItemKind::OpaqueTy(op_ty), ..
|
kind: hir::ItemKind::OpaqueTy(op_ty), ..
|
||||||
}) = self.tcx.hir_node(item_id.hir_id())
|
}) = self.tcx.hir_node(item_id.hir_id())
|
||||||
&& let [
|
&& let [hir::GenericBound::Trait(trait_ref, _)] = op_ty.bounds
|
||||||
hir::GenericBound::LangItemTrait(hir::LangItem::Future, _, _, generic_args),
|
&& let Some(hir::PathSegment { args: Some(generic_args), .. }) =
|
||||||
] = op_ty.bounds
|
trait_ref.trait_ref.path.segments.last()
|
||||||
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
|
&& let hir::GenericArgs { bindings: [ty_binding], .. } = generic_args
|
||||||
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } =
|
&& let hir::TypeBindingKind::Equality { term: hir::Term::Ty(term) } =
|
||||||
ty_binding.kind
|
ty_binding.kind
|
||||||
|
|
|
@ -668,26 +668,16 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
|
||||||
(
|
(
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }),
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: last_bounds, .. }),
|
||||||
hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }),
|
hir::ItemKind::OpaqueTy(hir::OpaqueTy { bounds: exp_bounds, .. }),
|
||||||
) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| {
|
) if std::iter::zip(*last_bounds, *exp_bounds).all(|(left, right)| match (
|
||||||
match (left, right) {
|
left, right,
|
||||||
(
|
) {
|
||||||
hir::GenericBound::Trait(tl, ml),
|
(hir::GenericBound::Trait(tl, ml), hir::GenericBound::Trait(tr, mr))
|
||||||
hir::GenericBound::Trait(tr, mr),
|
if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
|
||||||
) if tl.trait_ref.trait_def_id() == tr.trait_ref.trait_def_id()
|
|
||||||
&& ml == mr =>
|
&& ml == mr =>
|
||||||
{
|
{
|
||||||
true
|
true
|
||||||
}
|
}
|
||||||
(
|
|
||||||
hir::GenericBound::LangItemTrait(langl, _, _, argsl),
|
|
||||||
hir::GenericBound::LangItemTrait(langr, _, _, argsr),
|
|
||||||
) if langl == langr => {
|
|
||||||
// FIXME: consider the bounds!
|
|
||||||
debug!("{:?} {:?}", argsl, argsr);
|
|
||||||
true
|
|
||||||
}
|
|
||||||
_ => false,
|
_ => false,
|
||||||
}
|
|
||||||
}) =>
|
}) =>
|
||||||
{
|
{
|
||||||
StatementAsExpression::NeedsBoxing
|
StatementAsExpression::NeedsBoxing
|
||||||
|
|
|
@ -429,7 +429,7 @@ impl<'v> hir_visit::Visitor<'v> for StatCollector<'v> {
|
||||||
fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) {
|
fn visit_param_bound(&mut self, b: &'v hir::GenericBound<'v>) {
|
||||||
record_variants!(
|
record_variants!(
|
||||||
(self, b, b, Id::None, hir, GenericBound, GenericBound),
|
(self, b, b, Id::None, hir, GenericBound, GenericBound),
|
||||||
[Trait, LangItemTrait, Outlives]
|
[Trait, Outlives]
|
||||||
);
|
);
|
||||||
hir_visit::walk_param_bound(self, b)
|
hir_visit::walk_param_bound(self, b)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4783,8 +4783,14 @@ pub fn suggest_desugaring_async_fn_to_impl_future_in_trait<'tcx>(
|
||||||
};
|
};
|
||||||
|
|
||||||
let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
|
let future = tcx.hir_node_by_def_id(opaque_def_id).expect_item().expect_opaque_ty();
|
||||||
let Some(hir::GenericBound::LangItemTrait(_, _, _, generics)) = future.bounds.get(0) else {
|
let [hir::GenericBound::Trait(trait_ref, _)] = future.bounds else {
|
||||||
// `async fn` should always lower to a lang item bound... but don't ICE.
|
// `async fn` should always lower to a single bound... but don't ICE.
|
||||||
|
return None;
|
||||||
|
};
|
||||||
|
let Some(hir::PathSegment { args: Some(generics), .. }) =
|
||||||
|
trait_ref.trait_ref.path.segments.last()
|
||||||
|
else {
|
||||||
|
// desugaring to a single path segment for `Future<...>`.
|
||||||
return None;
|
return None;
|
||||||
};
|
};
|
||||||
let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) =
|
let Some(hir::TypeBindingKind::Equality { term: hir::Term::Ty(future_output_ty) }) =
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue