Skip to content

Commit cc79eaf

Browse files
bors[bot]xFrednet
andauthored
Merge #80
80: Fix ICE for `-> impl Trait` r=Niki4tap a=xFrednet This fixes an ICE for `-> impl Trait` representations. It doesn't work with `-> impl Trait<T>` yet, where `T` is a generic of the item. I'm not a 100% happy with how the rustc backend is structured, as it feels messy and hard to follow. I'm sadly not sure how to structure it better, as I've never worked on a translation layer like this in rust. My guess is that these things are always a bit messy, but I still hope to find a cleaner solution. For now, I hope that this is good enough. I also found a small bug with the refactoring from #66 that `cargo dogfood` didn't recompile the driver. It should now do that again :) r? `@Niki4tap` Co-authored-by: xFrednet <[email protected]>
2 parents 5c660c3 + 4e42c81 commit cc79eaf

File tree

5 files changed

+61
-53
lines changed

5 files changed

+61
-53
lines changed

cargo-marker/src/driver.rs

Lines changed: 2 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ pub fn print_driver_version() {
4141
}
4242

4343
/// This tries to install the rustc driver specified in [`DEFAULT_DRIVER_INFO`].
44-
pub fn install_driver(verbose: bool) -> Result<(), ExitStatus> {
44+
pub fn install_driver(verbose: bool, dev_build: bool) -> Result<(), ExitStatus> {
4545
// The toolchain, driver version and api version should ideally be configurable.
4646
// However, that will require more prototyping and has a low priority rn.
4747
// See #60
@@ -50,12 +50,7 @@ pub fn install_driver(verbose: bool) -> Result<(), ExitStatus> {
5050
let toolchain = &DEFAULT_DRIVER_INFO.toolchain;
5151
check_toolchain(toolchain)?;
5252

53-
build_driver(
54-
toolchain,
55-
&DEFAULT_DRIVER_INFO.version,
56-
verbose,
57-
cfg!(feature = "dev-build"),
58-
)?;
53+
build_driver(toolchain, &DEFAULT_DRIVER_INFO.version, verbose, dev_build)?;
5954

6055
// We don't want to advice the user, to install the driver again.
6156
check_driver(verbose, false)

cargo-marker/src/main.rs

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,21 +78,27 @@ fn main() -> Result<(), ExitStatus> {
7878
);
7979

8080
let verbose = matches.get_flag("verbose");
81+
let dev_build = cfg!(feature = "dev-build");
8182

8283
if matches.get_flag("version") {
8384
print_version(verbose);
8485
return Ok(());
8586
}
8687

8788
match matches.subcommand() {
88-
Some(("setup", _args)) => driver::install_driver(verbose),
89-
Some(("check", args)) => run_check(args, verbose),
90-
None => run_check(&matches, verbose),
89+
Some(("setup", _args)) => driver::install_driver(verbose, dev_build),
90+
Some(("check", args)) => run_check(args, verbose, dev_build),
91+
None => run_check(&matches, verbose, dev_build),
9192
_ => unreachable!(),
9293
}
9394
}
9495

95-
fn run_check(matches: &clap::ArgMatches, verbose: bool) -> Result<(), ExitStatus> {
96+
fn run_check(matches: &clap::ArgMatches, verbose: bool, dev_build: bool) -> Result<(), ExitStatus> {
97+
// If this is a dev build, we want to recompile the driver before checking
98+
if dev_build {
99+
driver::install_driver(verbose, dev_build)?;
100+
}
101+
96102
let mut lint_crates = vec![];
97103
if let Some(cmd_lint_crates) = matches.get_many::<OsString>("lints") {
98104
println!();

marker_driver_rustc/src/conversion/generic.rs

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,42 @@ use marker_api::ast::{
22
generic::{BindingGenericArg, GenericArgKind, GenericArgs, Lifetime, LifetimeKind, TraitBound, TyParamBound},
33
TraitRef,
44
};
5+
use rustc_hir as hir;
56

67
use crate::context::RustcContext;
78

89
use super::{to_generic_id, to_item_id, to_span_id, to_symbol_id, ty::TyConverter};
910

10-
pub fn to_api_lifetime<'ast>(
11-
_cx: &'ast RustcContext<'ast, '_>,
11+
pub fn conv_ast_bound<'ast, 'tcx>(
12+
cx: &'ast RustcContext<'ast, 'tcx>,
13+
bounds: &'tcx [hir::GenericBound],
14+
) -> &'ast [TyParamBound<'ast>] {
15+
if bounds.is_empty() {
16+
return &[];
17+
}
18+
19+
let bounds: Vec<_> = bounds
20+
.iter()
21+
.filter_map(|bound| match bound {
22+
hir::GenericBound::Trait(trait_ref, modifier) => Some(TyParamBound::TraitBound(cx.storage.alloc(|| {
23+
TraitBound::new(
24+
!matches!(modifier, hir::TraitBoundModifier::None),
25+
to_api_trait_ref(cx, &trait_ref.trait_ref),
26+
to_span_id(bound.span()),
27+
)
28+
}))),
29+
hir::GenericBound::LangItemTrait(_, _, _, _) => todo!(),
30+
hir::GenericBound::Outlives(rust_lt) => {
31+
to_api_lifetime(cx, rust_lt).map(|api_lt| TyParamBound::Lifetime(cx.storage.alloc(|| api_lt)))
32+
},
33+
})
34+
.collect();
35+
36+
cx.storage.alloc_slice_iter(bounds.into_iter())
37+
}
38+
39+
pub fn to_api_lifetime<'ast, 'tcx>(
40+
_cx: &'ast RustcContext<'ast, 'tcx>,
1241
rust_lt: &rustc_hir::Lifetime,
1342
) -> Option<Lifetime<'ast>> {
1443
let kind = match rust_lt.res {

marker_driver_rustc/src/conversion/item.rs

Lines changed: 5 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,5 @@
11
use marker_api::ast::{
2-
generic::{
3-
GenericParamKind, GenericParams, LifetimeClause, LifetimeParam, TraitBound, TyClause, TyParam, TyParamBound,
4-
WhereClauseKind,
5-
},
2+
generic::{GenericParamKind, GenericParams, LifetimeClause, LifetimeParam, TyClause, TyParam, WhereClauseKind},
63
item::{
74
AdtKind, AssocItemKind, CommonItemData, ConstItem, EnumItem, EnumVariant, ExternBlockItem, ExternCrateItem,
85
ExternItemKind, Field, FnItem, ImplItem, ItemKind, ModItem, StaticItem, StructItem, TraitItem, TyAliasItem,
@@ -16,7 +13,7 @@ use rustc_hir as hir;
1613
use crate::context::RustcContext;
1714

1815
use super::{
19-
generic::{to_api_lifetime, to_api_trait_ref},
16+
generic::{conv_ast_bound, to_api_lifetime, to_api_trait_ref},
2017
to_api_abi, to_api_body_id, to_api_path, to_generic_id, to_item_id, to_rustc_item_id, to_span_id, to_symbol_id,
2118
ty::TyConverter,
2219
};
@@ -115,7 +112,7 @@ impl<'ast, 'tcx> ItemConverter<'ast, 'tcx> {
115112
data,
116113
matches!(unsafety, hir::Unsafety::Unsafe),
117114
self.conv_generic(generics),
118-
self.conv_generic_bounds(bounds),
115+
conv_ast_bound(self.cx, bounds),
119116
self.conv_trait_items(items),
120117
)
121118
})),
@@ -219,7 +216,7 @@ impl<'ast, 'tcx> ItemConverter<'ast, 'tcx> {
219216
TyAliasItem::new(
220217
data,
221218
self.conv_generic(trait_item.generics),
222-
self.conv_generic_bounds(bounds),
219+
conv_ast_bound(self.cx, bounds),
223220
ty.map(|ty| self.conv_ty(ty)),
224221
)
225222
})),
@@ -310,31 +307,6 @@ impl<'ast, 'tcx> ItemConverter<'ast, 'tcx> {
310307
self.cx.storage.alloc_slice_iter(params.into_iter())
311308
}
312309

313-
fn conv_generic_bounds(&self, bounds: hir::GenericBounds<'tcx>) -> &'ast [TyParamBound<'ast>] {
314-
if bounds.is_empty() {
315-
return &[];
316-
}
317-
318-
let bounds: Vec<_> = bounds
319-
.iter()
320-
.filter_map(|bound| match bound {
321-
hir::GenericBound::Trait(trait_ref, modifier) => Some(TyParamBound::TraitBound(self.alloc(|| {
322-
TraitBound::new(
323-
!matches!(modifier, hir::TraitBoundModifier::None),
324-
to_api_trait_ref(self.cx, &trait_ref.trait_ref),
325-
to_span_id(bound.span()),
326-
)
327-
}))),
328-
hir::GenericBound::LangItemTrait(_, _, _, _) => todo!(),
329-
hir::GenericBound::Outlives(rust_lt) => {
330-
to_api_lifetime(self.cx, rust_lt).map(|api_lt| TyParamBound::Lifetime(self.alloc(|| api_lt)))
331-
},
332-
})
333-
.collect();
334-
335-
self.cx.storage.alloc_slice_iter(bounds.into_iter())
336-
}
337-
338310
fn conv_generic(&self, rustc_generics: &hir::Generics<'tcx>) -> GenericParams<'ast> {
339311
// FIXME: Update implementation to store the parameter bounds in the parameters
340312
let clauses: Vec<_> = rustc_generics
@@ -348,7 +320,7 @@ impl<'ast, 'tcx> ItemConverter<'ast, 'tcx> {
348320
let params = GenericParams::new(self.conv_generic_params(ty_bound.bound_generic_params), &[]);
349321
let ty = self.conv_ty(ty_bound.bounded_ty);
350322
Some(WhereClauseKind::Ty(self.alloc(|| {
351-
TyClause::new(Some(params), ty, self.conv_generic_bounds(predicate.bounds()))
323+
TyClause::new(Some(params), ty, conv_ast_bound(self.cx, predicate.bounds()))
352324
})))
353325
},
354326
hir::WherePredicate::RegionPredicate(lifetime_bound) => {

marker_driver_rustc/src/conversion/ty.rs

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
11
use marker_api::ast::{
22
ty::{
3-
AliasTy, ArrayTy, BoolTy, CommonTyData, EnumTy, FnTy, GenericTy, InferredTy, NeverTy, NumKind, NumTy, RawPtrTy,
4-
RefTy, RelativeTy, SelfTy, SliceTy, StructTy, TextKind, TextTy, TraitObjTy, TupleTy, TyKind, UnionTy,
3+
AliasTy, ArrayTy, BoolTy, CommonTyData, EnumTy, FnTy, GenericTy, ImplTraitTy, InferredTy, NeverTy, NumKind,
4+
NumTy, RawPtrTy, RefTy, RelativeTy, SelfTy, SliceTy, StructTy, TextKind, TextTy, TraitObjTy, TupleTy, TyKind,
5+
UnionTy,
56
},
67
CommonCallableData, Parameter,
78
};
@@ -12,7 +13,7 @@ use crate::{
1213
};
1314

1415
use super::{
15-
generic::{to_api_generic_args, to_api_lifetime, to_api_trait_bounds_from_hir},
16+
generic::{conv_ast_bound, to_api_generic_args, to_api_lifetime, to_api_trait_bounds_from_hir},
1617
to_generic_id, to_item_id, to_span_id, to_ty_def_id,
1718
};
1819

@@ -82,10 +83,15 @@ impl<'ast, 'tcx> TyConverter<'ast, 'tcx> {
8283
TyKind::Tuple(self.cx.storage.alloc(|| TupleTy::new(data, api_tys)))
8384
},
8485
hir::TyKind::Path(qpath) => self.conv_syn_qpath(data, qpath),
85-
hir::TyKind::OpaqueDef(_, _, _) => {
86-
// This requires function items to be implemented. Therefore we'll leave this as an open TODO for
87-
// now
88-
todo!("{:#?}", rustc_ty)
86+
hir::TyKind::OpaqueDef(id, _, _) => {
87+
// `impl Trait` in rustc are implemented as Items with the kind `OpaqueTy`
88+
let item = self.cx.rustc_cx.hir().item(*id);
89+
let hir::ItemKind::OpaqueTy(opty) = &item.kind else {
90+
unreachable!("the item of a `OpaqueDef` should be `OpaqueTy` {item:#?}");
91+
};
92+
let rust_bound = conv_ast_bound(self.cx, opty.bounds);
93+
// FIXME: Generics are a bit weird with opaque types
94+
TyKind::ImplTrait(self.cx.storage.alloc(|| ImplTraitTy::new(data, rust_bound)))
8995
},
9096
hir::TyKind::TraitObject(rust_bounds, rust_lt, _syntax) => TyKind::TraitObj(
9197
self.cx

0 commit comments

Comments
 (0)