Skip to content

Implement Chalk's debug methods using TLS #3748

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 1 commit into from
Apr 10, 2020
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
7 changes: 7 additions & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions crates/ra_hir_ty/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@ ra_prof = { path = "../ra_prof" }
ra_syntax = { path = "../ra_syntax" }
test_utils = { path = "../test_utils" }

scoped-tls = "1"

chalk-solve = { git = "https://github.com/rust-lang/chalk.git", rev = "039fc904a05f8cb3d0c682c9a57a63dda7a35356" }
chalk-rust-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "039fc904a05f8cb3d0c682c9a57a63dda7a35356" }
chalk-ir = { git = "https://github.com/rust-lang/chalk.git", rev = "039fc904a05f8cb3d0c682c9a57a63dda7a35356" }
Expand Down
26 changes: 14 additions & 12 deletions crates/ra_hir_ty/src/display.rs
Original file line number Diff line number Diff line change
Expand Up @@ -247,19 +247,21 @@ impl HirDisplay for ApplicationTy {
}
}
TypeCtor::Closure { .. } => {
let sig = self.parameters[0]
.callable_sig(f.db)
.expect("first closure parameter should contain signature");
if sig.params().is_empty() {
write!(f, "||")?;
} else if f.omit_verbose_types() {
write!(f, "|{}|", TYPE_HINT_TRUNCATION)?;
let sig = self.parameters[0].callable_sig(f.db);
if let Some(sig) = sig {
if sig.params().is_empty() {
write!(f, "||")?;
} else if f.omit_verbose_types() {
write!(f, "|{}|", TYPE_HINT_TRUNCATION)?;
} else {
write!(f, "|")?;
f.write_joined(sig.params(), ", ")?;
write!(f, "|")?;
};
write!(f, " -> {}", sig.ret().display(f.db))?;
} else {
write!(f, "|")?;
f.write_joined(sig.params(), ", ")?;
write!(f, "|")?;
};
write!(f, " -> {}", sig.ret().display(f.db))?;
write!(f, "{{closure}}")?;
}
}
}
Ok(())
Expand Down
13 changes: 11 additions & 2 deletions crates/ra_hir_ty/src/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -177,20 +177,29 @@ fn solve(

let fuel = std::cell::Cell::new(CHALK_SOLVER_FUEL);

let solution = solver.solve_limited(&context, goal, || {
let should_continue = || {
context.db.check_canceled();
let remaining = fuel.get();
fuel.set(remaining - 1);
if remaining == 0 {
log::debug!("fuel exhausted");
}
remaining > 0
});
};
let mut solve = || solver.solve_limited(&context, goal, should_continue);
// don't set the TLS for Chalk unless Chalk debugging is active, to make
// extra sure we only use it for debugging
let solution =
if is_chalk_debug() { chalk::tls::set_current_program(db, solve) } else { solve() };

log::debug!("solve({:?}) => {:?}", goal, solution);
solution
}

fn is_chalk_debug() -> bool {
std::env::var("CHALK_DEBUG").is_ok()
}

fn solution_from_chalk(
db: &dyn HirDatabase,
solution: chalk_solve::Solution<Interner>,
Expand Down
81 changes: 39 additions & 42 deletions crates/ra_hir_ty/src/traits/chalk.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ use crate::{
ProjectionTy, Substs, TraitRef, Ty, TypeCtor,
};

pub(super) mod tls;

#[derive(Debug, Copy, Clone, Hash, PartialOrd, Ord, PartialEq, Eq)]
pub struct Interner;

Expand All @@ -33,90 +35,85 @@ impl chalk_ir::interner::Interner for Interner {
type Identifier = TypeAliasId;
type DefId = InternId;

// FIXME: implement these
fn debug_struct_id(
_type_kind_id: chalk_ir::StructId<Self>,
_fmt: &mut fmt::Formatter<'_>,
type_kind_id: StructId,
fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
tls::with_current_program(|prog| Some(prog?.debug_struct_id(type_kind_id, fmt)))
}

fn debug_trait_id(
_type_kind_id: chalk_ir::TraitId<Self>,
_fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
fn debug_trait_id(type_kind_id: TraitId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
tls::with_current_program(|prog| Some(prog?.debug_trait_id(type_kind_id, fmt)))
}

fn debug_assoc_type_id(
_id: chalk_ir::AssocTypeId<Self>,
_fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
fn debug_assoc_type_id(id: AssocTypeId, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
tls::with_current_program(|prog| Some(prog?.debug_assoc_type_id(id, fmt)))
}

fn debug_alias(
_projection: &chalk_ir::AliasTy<Self>,
_fmt: &mut fmt::Formatter<'_>,
alias: &chalk_ir::AliasTy<Interner>,
fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
tls::with_current_program(|prog| Some(prog?.debug_alias(alias, fmt)))
}

fn debug_ty(_ty: &chalk_ir::Ty<Self>, _fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
None
fn debug_ty(ty: &chalk_ir::Ty<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
tls::with_current_program(|prog| Some(prog?.debug_ty(ty, fmt)))
}

fn debug_lifetime(
_lifetime: &chalk_ir::Lifetime<Self>,
_fmt: &mut fmt::Formatter<'_>,
lifetime: &chalk_ir::Lifetime<Interner>,
fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
tls::with_current_program(|prog| Some(prog?.debug_lifetime(lifetime, fmt)))
}

fn debug_parameter(
_parameter: &Parameter<Self>,
_fmt: &mut fmt::Formatter<'_>,
parameter: &Parameter<Interner>,
fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
tls::with_current_program(|prog| Some(prog?.debug_parameter(parameter, fmt)))
}

fn debug_goal(_goal: &Goal<Self>, _fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
None
fn debug_goal(goal: &Goal<Interner>, fmt: &mut fmt::Formatter<'_>) -> Option<fmt::Result> {
tls::with_current_program(|prog| Some(prog?.debug_goal(goal, fmt)))
}

fn debug_goals(
_goals: &chalk_ir::Goals<Self>,
_fmt: &mut fmt::Formatter<'_>,
goals: &chalk_ir::Goals<Interner>,
fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
tls::with_current_program(|prog| Some(prog?.debug_goals(goals, fmt)))
}

fn debug_program_clause_implication(
_pci: &chalk_ir::ProgramClauseImplication<Self>,
_fmt: &mut fmt::Formatter<'_>,
pci: &chalk_ir::ProgramClauseImplication<Interner>,
fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
tls::with_current_program(|prog| Some(prog?.debug_program_clause_implication(pci, fmt)))
}

fn debug_application_ty(
_application_ty: &chalk_ir::ApplicationTy<Self>,
_fmt: &mut fmt::Formatter<'_>,
application_ty: &chalk_ir::ApplicationTy<Interner>,
fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
tls::with_current_program(|prog| Some(prog?.debug_application_ty(application_ty, fmt)))
}

fn debug_substitution(
_substitution: &chalk_ir::Substitution<Self>,
_fmt: &mut fmt::Formatter<'_>,
substitution: &chalk_ir::Substitution<Interner>,
fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
tls::with_current_program(|prog| Some(prog?.debug_substitution(substitution, fmt)))
}

fn debug_separator_trait_ref(
_separator_trait_ref: &chalk_ir::SeparatorTraitRef<Self>,
_fmt: &mut fmt::Formatter<'_>,
separator_trait_ref: &chalk_ir::SeparatorTraitRef<Interner>,
fmt: &mut fmt::Formatter<'_>,
) -> Option<fmt::Result> {
None
tls::with_current_program(|prog| {
Some(prog?.debug_separator_trait_ref(separator_trait_ref, fmt))
})
}

fn intern_ty(&self, ty: chalk_ir::TyData<Self>) -> Box<chalk_ir::TyData<Self>> {
Expand Down
Loading