Skip to content

Fix ICE for -> impl Trait #80

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

Merged
merged 2 commits into from
Jan 6, 2023
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
9 changes: 2 additions & 7 deletions cargo-marker/src/driver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ pub fn print_driver_version() {
}

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

build_driver(
toolchain,
&DEFAULT_DRIVER_INFO.version,
verbose,
cfg!(feature = "dev-build"),
)?;
build_driver(toolchain, &DEFAULT_DRIVER_INFO.version, verbose, dev_build)?;

// We don't want to advice the user, to install the driver again.
check_driver(verbose, false)
Expand Down
14 changes: 10 additions & 4 deletions cargo-marker/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -78,21 +78,27 @@ fn main() -> Result<(), ExitStatus> {
);

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

if matches.get_flag("version") {
print_version(verbose);
return Ok(());
}

match matches.subcommand() {
Some(("setup", _args)) => driver::install_driver(verbose),
Some(("check", args)) => run_check(args, verbose),
None => run_check(&matches, verbose),
Some(("setup", _args)) => driver::install_driver(verbose, dev_build),
Some(("check", args)) => run_check(args, verbose, dev_build),
None => run_check(&matches, verbose, dev_build),
_ => unreachable!(),
}
}

fn run_check(matches: &clap::ArgMatches, verbose: bool) -> Result<(), ExitStatus> {
fn run_check(matches: &clap::ArgMatches, verbose: bool, dev_build: bool) -> Result<(), ExitStatus> {
// If this is a dev build, we want to recompile the driver before checking
if dev_build {
driver::install_driver(verbose, dev_build)?;
}

let mut lint_crates = vec![];
if let Some(cmd_lint_crates) = matches.get_many::<OsString>("lints") {
println!();
Expand Down
33 changes: 31 additions & 2 deletions marker_driver_rustc/src/conversion/generic.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,42 @@ use marker_api::ast::{
generic::{BindingGenericArg, GenericArgKind, GenericArgs, Lifetime, LifetimeKind, TraitBound, TyParamBound},
TraitRef,
};
use rustc_hir as hir;

use crate::context::RustcContext;

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

pub fn to_api_lifetime<'ast>(
_cx: &'ast RustcContext<'ast, '_>,
pub fn conv_ast_bound<'ast, 'tcx>(
cx: &'ast RustcContext<'ast, 'tcx>,
bounds: &'tcx [hir::GenericBound],
) -> &'ast [TyParamBound<'ast>] {
if bounds.is_empty() {
return &[];
}

let bounds: Vec<_> = bounds
.iter()
.filter_map(|bound| match bound {
hir::GenericBound::Trait(trait_ref, modifier) => Some(TyParamBound::TraitBound(cx.storage.alloc(|| {
TraitBound::new(
!matches!(modifier, hir::TraitBoundModifier::None),
to_api_trait_ref(cx, &trait_ref.trait_ref),
to_span_id(bound.span()),
)
}))),
hir::GenericBound::LangItemTrait(_, _, _, _) => todo!(),
hir::GenericBound::Outlives(rust_lt) => {
to_api_lifetime(cx, rust_lt).map(|api_lt| TyParamBound::Lifetime(cx.storage.alloc(|| api_lt)))
},
})
.collect();

cx.storage.alloc_slice_iter(bounds.into_iter())
}

pub fn to_api_lifetime<'ast, 'tcx>(
_cx: &'ast RustcContext<'ast, 'tcx>,
rust_lt: &rustc_hir::Lifetime,
) -> Option<Lifetime<'ast>> {
let kind = match rust_lt.res {
Expand Down
38 changes: 5 additions & 33 deletions marker_driver_rustc/src/conversion/item.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,5 @@
use marker_api::ast::{
generic::{
GenericParamKind, GenericParams, LifetimeClause, LifetimeParam, TraitBound, TyClause, TyParam, TyParamBound,
WhereClauseKind,
},
generic::{GenericParamKind, GenericParams, LifetimeClause, LifetimeParam, TyClause, TyParam, WhereClauseKind},
item::{
AdtKind, AssocItemKind, CommonItemData, ConstItem, EnumItem, EnumVariant, ExternBlockItem, ExternCrateItem,
ExternItemKind, Field, FnItem, ImplItem, ItemKind, ModItem, StaticItem, StructItem, TraitItem, TyAliasItem,
Expand All @@ -16,7 +13,7 @@ use rustc_hir as hir;
use crate::context::RustcContext;

use super::{
generic::{to_api_lifetime, to_api_trait_ref},
generic::{conv_ast_bound, to_api_lifetime, to_api_trait_ref},
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,
ty::TyConverter,
};
Expand Down Expand Up @@ -115,7 +112,7 @@ impl<'ast, 'tcx> ItemConverter<'ast, 'tcx> {
data,
matches!(unsafety, hir::Unsafety::Unsafe),
self.conv_generic(generics),
self.conv_generic_bounds(bounds),
conv_ast_bound(self.cx, bounds),
self.conv_trait_items(items),
)
})),
Expand Down Expand Up @@ -219,7 +216,7 @@ impl<'ast, 'tcx> ItemConverter<'ast, 'tcx> {
TyAliasItem::new(
data,
self.conv_generic(trait_item.generics),
self.conv_generic_bounds(bounds),
conv_ast_bound(self.cx, bounds),
ty.map(|ty| self.conv_ty(ty)),
)
})),
Expand Down Expand Up @@ -310,31 +307,6 @@ impl<'ast, 'tcx> ItemConverter<'ast, 'tcx> {
self.cx.storage.alloc_slice_iter(params.into_iter())
}

fn conv_generic_bounds(&self, bounds: hir::GenericBounds<'tcx>) -> &'ast [TyParamBound<'ast>] {
if bounds.is_empty() {
return &[];
}

let bounds: Vec<_> = bounds
.iter()
.filter_map(|bound| match bound {
hir::GenericBound::Trait(trait_ref, modifier) => Some(TyParamBound::TraitBound(self.alloc(|| {
TraitBound::new(
!matches!(modifier, hir::TraitBoundModifier::None),
to_api_trait_ref(self.cx, &trait_ref.trait_ref),
to_span_id(bound.span()),
)
}))),
hir::GenericBound::LangItemTrait(_, _, _, _) => todo!(),
hir::GenericBound::Outlives(rust_lt) => {
to_api_lifetime(self.cx, rust_lt).map(|api_lt| TyParamBound::Lifetime(self.alloc(|| api_lt)))
},
})
.collect();

self.cx.storage.alloc_slice_iter(bounds.into_iter())
}

fn conv_generic(&self, rustc_generics: &hir::Generics<'tcx>) -> GenericParams<'ast> {
// FIXME: Update implementation to store the parameter bounds in the parameters
let clauses: Vec<_> = rustc_generics
Expand All @@ -348,7 +320,7 @@ impl<'ast, 'tcx> ItemConverter<'ast, 'tcx> {
let params = GenericParams::new(self.conv_generic_params(ty_bound.bound_generic_params), &[]);
let ty = self.conv_ty(ty_bound.bounded_ty);
Some(WhereClauseKind::Ty(self.alloc(|| {
TyClause::new(Some(params), ty, self.conv_generic_bounds(predicate.bounds()))
TyClause::new(Some(params), ty, conv_ast_bound(self.cx, predicate.bounds()))
})))
},
hir::WherePredicate::RegionPredicate(lifetime_bound) => {
Expand Down
20 changes: 13 additions & 7 deletions marker_driver_rustc/src/conversion/ty.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,8 @@
use marker_api::ast::{
ty::{
AliasTy, ArrayTy, BoolTy, CommonTyData, EnumTy, FnTy, GenericTy, InferredTy, NeverTy, NumKind, NumTy, RawPtrTy,
RefTy, RelativeTy, SelfTy, SliceTy, StructTy, TextKind, TextTy, TraitObjTy, TupleTy, TyKind, UnionTy,
AliasTy, ArrayTy, BoolTy, CommonTyData, EnumTy, FnTy, GenericTy, ImplTraitTy, InferredTy, NeverTy, NumKind,
NumTy, RawPtrTy, RefTy, RelativeTy, SelfTy, SliceTy, StructTy, TextKind, TextTy, TraitObjTy, TupleTy, TyKind,
UnionTy,
},
CommonCallableData, Parameter,
};
Expand All @@ -12,7 +13,7 @@ use crate::{
};

use super::{
generic::{to_api_generic_args, to_api_lifetime, to_api_trait_bounds_from_hir},
generic::{conv_ast_bound, to_api_generic_args, to_api_lifetime, to_api_trait_bounds_from_hir},
to_generic_id, to_item_id, to_span_id, to_ty_def_id,
};

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