diff --git a/Cargo.lock b/Cargo.lock index 0aa2789..e08ed4f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -461,8 +461,6 @@ checksum = "c08c74e62047bb2de4ff487b251e4a92e24f48745648451635cec7d591162d9f" [[package]] name = "rustc_plugin" version = "0.9.0-nightly-2024-01-24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0abfa69e634af1147ebcfd86ac7e7b745e2b2e9092f2e7f4852358ab99dfb19b" dependencies = [ "cargo_metadata", "log", @@ -481,8 +479,6 @@ checksum = "b3c5a95edfa0c893236ae4778bb7c4752760e4c0d245e19b5eff33c5aa5eb9dc" [[package]] name = "rustc_utils" version = "0.9.0-nightly-2024-01-24" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb3ed9a0c4c18c1973477a672cc6cf7b362e4b3d0ae6acdc5c455421e0d5e69d" dependencies = [ "anyhow", "cfg-if", diff --git a/Cargo.toml b/Cargo.toml index 68a0009..7b13779 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -5,3 +5,7 @@ resolver = "2" [profile.dev.package.similar] opt-level = 3 + +[patch.crates-io] +rustc_utils = { path = "../rustc-plugin/crates/rustc_utils" } +rustc_plugin = { path = "../rustc-plugin/crates/rustc_plugin" } diff --git a/README.md b/README.md index c1f5ad5..ff0986d 100644 --- a/README.md +++ b/README.md @@ -46,7 +46,7 @@ If rustup fails, especially with an error like "could not rename the downloaded To solve the issue, go to the command line and run: ``` -rustup toolchain install nightly-2024-01-24 -c rust-src -c rustc-dev -c llvm-tools-preview +rustup toolchain install nightly-2024-04-08 -c rust-src -c rustc-dev -c llvm-tools-preview ``` Then go back to VSCode and click "Continue" to let Argus continue installing. diff --git a/crates/argus/src/analysis/entry.rs b/crates/argus/src/analysis/entry.rs index d67dc4d..82dba62 100644 --- a/crates/argus/src/analysis/entry.rs +++ b/crates/argus/src/analysis/entry.rs @@ -29,6 +29,7 @@ use crate::{ fluid_let! { pub static INSPECTING: bool; + pub static BODY_ID: BodyId; } macro_rules! guard_inspection { @@ -55,8 +56,7 @@ pub fn process_obligation<'tcx>( ) { guard_inspection! {} - let Some(_ldef_id) = infcx.body_id() else { - log::warn!("Skipping obligation unassociated with local body {obl:?}"); + let Some(body_id) = BODY_ID.copied() else { return; }; @@ -89,7 +89,8 @@ pub fn process_obligation<'tcx>( None }; - let obligation = transform::compute_provenance(infcx, obl, result, dataid); + let obligation = + transform::compute_provenance(body_id, infcx, obl, result, dataid); tls::store_obligation(obligation); @@ -195,11 +196,13 @@ fn generate_tree<'tcx>( predicate: obligation.predicate, param_env: obligation.param_env, }; - let item_def_id = infcx - .body_id() - .ok_or(anyhow!("body not local"))? - .to_def_id(); - serialize_proof_tree(goal, infcx, item_def_id) + + let Some(body_id) = BODY_ID.copied() else { + bail!("missing body id"); + }; + + let body_owner = infcx.tcx.hir().body_owner_def_id(body_id).to_def_id(); + serialize_proof_tree(goal, infcx, body_owner) } pub(in crate::analysis) fn build_obligations_in_body<'tcx>( diff --git a/crates/argus/src/analysis/hir.rs b/crates/argus/src/analysis/hir.rs index 024c1ae..8397028 100644 --- a/crates/argus/src/analysis/hir.rs +++ b/crates/argus/src/analysis/hir.rs @@ -193,14 +193,13 @@ macro_rules! simple_visitors { impl HirVisitor<'_> for FindNodeBySpan { simple_visitors! { [visit_param, walk_param, hir::Param], - [visit_local, walk_local, hir::Local], + [visit_local, walk_local, hir::LetStmt], [visit_block, walk_block, hir::Block], [visit_stmt, walk_stmt, hir::Stmt], [visit_arm, walk_arm, hir::Arm], [visit_pat, walk_pat, hir::Pat], [visit_pat_field, walk_pat_field, hir::PatField], [visit_expr, walk_expr, hir::Expr], - [visit_let_expr, walk_let_expr, hir::Let], [visit_expr_field, walk_expr_field, hir::ExprField], [visit_ty, walk_ty, hir::Ty], [visit_generic_param, walk_generic_param, hir::GenericParam], diff --git a/crates/argus/src/analysis/mod.rs b/crates/argus/src/analysis/mod.rs index 2d3f60c..d7ad419 100644 --- a/crates/argus/src/analysis/mod.rs +++ b/crates/argus/src/analysis/mod.rs @@ -34,7 +34,7 @@ pub fn obligations<'tcx>( body_id: BodyId, ) -> Result { rustc_middle::ty::print::with_no_trimmed_paths! {{ - log::info!("Typeck'ing body {body_id:?}"); + fluid_let::fluid_set!(entry::BODY_ID, body_id); let typeck_results = tcx.inspect_typeck(body_id, entry::process_obligation); @@ -50,6 +50,8 @@ pub fn tree<'tcx>( body_id: BodyId, ) -> Result { rustc_middle::ty::print::with_no_trimmed_paths! {{ + fluid_let::fluid_set!(entry::BODY_ID, body_id); + let typeck_results = tcx.inspect_typeck(body_id, entry::process_obligation_for_tree); @@ -62,6 +64,8 @@ pub fn tree<'tcx>( /// NOTE: this requires quite a bit of memory as everything is generated eagerly, favor /// using a combination of `obligation` and `tree` analyses for a reduced memory footprint. pub fn bundle<'tcx>(tcx: TyCtxt<'tcx>, body_id: BodyId) -> Result { + fluid_let::fluid_set!(entry::BODY_ID, body_id); + let (full_data, obligations_in_body) = body_data(tcx, body_id)?; let t = (&*full_data, &obligations_in_body); let thunk = || t; @@ -82,6 +86,7 @@ pub fn bundle<'tcx>(tcx: TyCtxt<'tcx>, body_id: BodyId) -> Result { .prefer_local() .to_string_lossy() .to_string(); + Ok(BodyBundle { filename, body: obligations_in_body, diff --git a/crates/argus/src/analysis/tls.rs b/crates/argus/src/analysis/tls.rs index 2fb67b0..111ab9e 100644 --- a/crates/argus/src/analysis/tls.rs +++ b/crates/argus/src/analysis/tls.rs @@ -119,7 +119,7 @@ pub fn replace_reported_errors(infcx: &InferCtxt) { .reported_trait_errors .borrow() .iter() - .map(|(span, predicates)| { + .map(|(span, (predicates, _))| { ( *span, predicates diff --git a/crates/argus/src/analysis/transform.rs b/crates/argus/src/analysis/transform.rs index 1110899..02605c2 100644 --- a/crates/argus/src/analysis/transform.rs +++ b/crates/argus/src/analysis/transform.rs @@ -40,21 +40,17 @@ macro_rules! property_is_ok { } pub fn compute_provenance<'tcx>( + body_id: BodyId, infcx: &InferCtxt<'tcx>, obligation: &PredicateObligation<'tcx>, result: EvaluationResult, dataid: Option, ) -> Provenance { - let Some(ldef_id) = infcx.body_id() else { - unreachable!("argus analysis should only happen on local bodies"); - }; - let hir = infcx.tcx.hir(); let fdata = infcx.bless_fulfilled(obligation, result, false); // If the span is coming from a macro, point to the callsite. let callsite_cause_span = fdata.obligation.cause.span.source_callsite(); - let body_id = hir.body_owned_by(ldef_id); let hir_id = hier_hir::find_most_enclosing_node( &infcx.tcx, body_id, @@ -220,16 +216,15 @@ impl<'a, 'tcx: 'a> ObligationsBuilder<'a, 'tcx> { BinKind::Call => Call, BinKind::MethodReceiver => MethodReceiver, BinKind::MethodCall => { - let Some(hir::Node::Expr( + let hir::Node::Expr( call_expr @ hir::Expr { kind: hir::ExprKind::MethodCall(segment, recvr, args, call_span), .. }, - )) = hir.find(hir_id) + ) = hir.hir_node(hir_id) else { unreachable!( - "Bin kind `MethodCall` for non `ExprKind::MethodCall` {:?}", - hir.node_to_string(hir_id) + "bin kind is method call, but node is not method call" ); }; @@ -517,19 +512,11 @@ impl<'a, 'tcx: 'a> ObligationsBuilder<'a, 'tcx> { let ty_id = |ty: Ty<'tcx>| ty; - let ty_with_ref = move |ty: Ty<'tcx>| { - Ty::new_ref(tcx, region, ty::TypeAndMut { - ty, - mutbl: hir::Mutability::Not, - }) - }; + let ty_with_ref = + move |ty: Ty<'tcx>| Ty::new_ref(tcx, region, ty, hir::Mutability::Not); - let ty_with_mut_ref = move |ty: Ty<'tcx>| { - Ty::new_ref(tcx, region, ty::TypeAndMut { - ty, - mutbl: hir::Mutability::Mut, - }) - }; + let ty_with_mut_ref = + move |ty: Ty<'tcx>| Ty::new_ref(tcx, region, ty, hir::Mutability::Mut); // TODO: rustc also considers raw pointers, ignoring for now ... let ty_mutators: Vec<&dyn Fn(Ty<'tcx>) -> Ty<'tcx>> = @@ -580,8 +567,13 @@ impl<'a, 'tcx: 'a> ObligationsBuilder<'a, 'tcx> { infcx.probe(|_| { let res = infcx.evaluate_obligation(&obligation); - let mut with_provenance = - compute_provenance(&infcx, &obligation, res, None); + let mut with_provenance = compute_provenance( + self.body_id, + &infcx, + &obligation, + res, + None, + ); let syn_id = self.synthetic_data.add(SyntheticData { full_data: full_query_idx, @@ -743,12 +735,9 @@ mod tree_search { } impl<'tcx> ProofTreeVisitor<'tcx> for BranchlessSearch { - type BreakTy = (); + type Result = ControlFlow<()>; - fn visit_goal( - &mut self, - goal: &InspectGoal<'_, 'tcx>, - ) -> ControlFlow { + fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> Self::Result { let infcx = goal.infcx(); let predicate = &goal.goal().predicate; let hash = infcx.predicate_hash(predicate).into(); diff --git a/crates/argus/src/ext.rs b/crates/argus/src/ext.rs index 8cec016..dd6c4b7 100644 --- a/crates/argus/src/ext.rs +++ b/crates/argus/src/ext.rs @@ -2,10 +2,7 @@ use rustc_data_structures::{ fx::FxIndexMap, stable_hasher::{Hash64, HashStable, StableHasher}, }; -use rustc_hir::{ - def_id::{DefId, LocalDefId}, - BodyId, HirId, -}; +use rustc_hir::{def_id::DefId, BodyId, HirId}; use rustc_hir_typeck::inspect_typeck; use rustc_infer::{ infer::InferCtxt, @@ -201,8 +198,6 @@ pub trait InferCtxtExt<'tcx> { obligation: &PredicateObligation<'tcx>, ) -> ObligationNecessity; - fn body_id(&self) -> Option; - fn predicate_hash(&self, p: &Predicate<'tcx>) -> Hash64; fn evaluate_obligation( @@ -270,7 +265,7 @@ pub fn group_predicates_by_ty<'tcx>( let trait_ref = poly_trait_pred.map_bound(|tr| tr.trait_ref).skip_binder(); let bound = ClauseBound::Trait( - poly_trait_pred.polarity(), + poly_trait_pred.polarity().into(), TraitRefPrintOnlyTraitPathDef(trait_ref), ); grouped.entry(ty).or_default().push(bound); @@ -314,7 +309,7 @@ impl<'tcx> TyCtxtExt<'tcx> for TyCtxt<'tcx> { let tcx = *self; let impl_def_id = def_id; - // From [`rustc_trait_selection::traits::specialize`] + // From [`rustc_trait_selection::traits::specialize::to_pretty_impl_header`] log::debug!( "Serializing this impl header\n{}", rustc::to_pretty_impl_header(tcx, impl_def_id) @@ -347,7 +342,10 @@ impl<'tcx> TyCtxtExt<'tcx> for TyCtxt<'tcx> { if let Some(poly_trait_ref) = p.as_trait_clause() { if Some(poly_trait_ref.def_id()) == sized_trait { types_without_default_bounds - .remove(&poly_trait_ref.self_ty().skip_binder()); + // NOTE: we don't rely on the ordering of the types without bounds here, + // so `swap_remove` is preferred because it's O(1) instead of `shift_remove` + // which is O(n). + .swap_remove(&poly_trait_ref.self_ty().skip_binder()); continue; } } @@ -484,16 +482,6 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { } } - // TODO there has to be a better way to do this, right? - fn body_id(&self) -> Option { - use rustc_infer::traits::DefiningAnchor::*; - if let Bind(ldef_id) = self.defining_use_anchor { - Some(ldef_id) - } else { - None - } - } - fn predicate_hash(&self, p: &Predicate<'tcx>) -> Hash64 { let mut freshener = rustc_infer::infer::TypeFreshener::new(self); let p = p.fold_with(&mut freshener); @@ -556,7 +544,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { .evaluate_root_goal(obligation.clone().into(), GenerateProofTree::Never) .0 { - Ok((_, c, _)) => Ok(c), + Ok((_, c)) => Ok(c), _ => Err(NoSolution), } } diff --git a/crates/argus/src/proof_tree/ext.rs b/crates/argus/src/proof_tree/ext.rs index 1769212..d7b6078 100644 --- a/crates/argus/src/proof_tree/ext.rs +++ b/crates/argus/src/proof_tree/ext.rs @@ -32,7 +32,7 @@ impl EvaluationResultExt for EvaluationResult { fn pretty(&self) -> String { let str = match self { Ok(Certainty::Yes) => "Yes", - Ok(Certainty::Maybe(MaybeCause::Overflow)) => "No: Overflow", + Ok(Certainty::Maybe(MaybeCause::Overflow { .. })) => "No: Overflow", Ok(Certainty::Maybe(MaybeCause::Ambiguity)) => "No: Ambiguity", Err(NoSolution) => "No", }; @@ -48,8 +48,10 @@ impl CandidateExt for InspectCandidate<'_, '_> { ProbeKind::NormalizedSelfTyAssembly => { "normalized-self-ty-asm".to_string() } + ProbeKind::TryNormalizeNonRigid { .. } => { + "try-normalize-non-rigid".to_string() + } ProbeKind::UnsizeAssembly => "unsize-asm".to_string(), - ProbeKind::CommitIfOk => "commit-if-ok".to_string(), ProbeKind::UpcastProjectionCompatibility => { "upcase-proj-compat".to_string() } diff --git a/crates/argus/src/proof_tree/interners.rs b/crates/argus/src/proof_tree/interners.rs index ba8f671..83e67e6 100644 --- a/crates/argus/src/proof_tree/interners.rs +++ b/crates/argus/src/proof_tree/interners.rs @@ -116,8 +116,10 @@ impl Interners { ProbeKind::NormalizedSelfTyAssembly => { self.intern_can_string("normalized-self-ty-asm") } + ProbeKind::TryNormalizeNonRigid { .. } => { + self.intern_can_string("try-normalize-non-rigid") + } ProbeKind::UnsizeAssembly => self.intern_can_string("unsize-asm"), - ProbeKind::CommitIfOk => self.intern_can_string("commit-if-ok"), ProbeKind::UpcastProjectionCompatibility => { self.intern_can_string("upcase-proj-compat") } diff --git a/crates/argus/src/proof_tree/serialize.rs b/crates/argus/src/proof_tree/serialize.rs index e6a7187..173893a 100644 --- a/crates/argus/src/proof_tree/serialize.rs +++ b/crates/argus/src/proof_tree/serialize.rs @@ -119,12 +119,9 @@ impl SerializedTreeVisitor { } impl<'tcx> ProofTreeVisitor<'tcx> for SerializedTreeVisitor { - type BreakTy = !; + type Result = (); - fn visit_goal( - &mut self, - goal: &InspectGoal<'_, 'tcx>, - ) -> ControlFlow { + fn visit_goal(&mut self, goal: &InspectGoal<'_, 'tcx>) -> Self::Result { let here_node = self.interners.mk_goal_node(goal); let here_idx = self.nodes.push(here_node.clone()); @@ -161,14 +158,12 @@ impl<'tcx> ProofTreeVisitor<'tcx> for SerializedTreeVisitor { let candidate_idx = self.nodes.push(here_candidate); self.topology.add(here_idx, candidate_idx); self.previous = Some(candidate_idx); - c.visit_nested(self)?; + c.visit_nested(self); add_result_if_empty(self, candidate_idx); } add_result_if_empty(self, here_idx); self.previous = here_parent; - - ControlFlow::Continue(()) } } diff --git a/crates/argus/src/rustc/fn_ctx.rs b/crates/argus/src/rustc/fn_ctx.rs index bd862c7..399d60a 100644 --- a/crates/argus/src/rustc/fn_ctx.rs +++ b/crates/argus/src/rustc/fn_ctx.rs @@ -250,7 +250,7 @@ impl<'a, 'tcx: 'a> FnCtxtExt<'tcx> for FnCtxtSimulator<'a, 'tcx> { hir_id: call_hir_id, span: call_span, .. - }) = hir.get_parent(hir_id) + }) = self.tcx.parent_hir_node(hir_id) && callee.hir_id == hir_id { if self.closure_span_overlaps_error(error, *call_span) { @@ -498,22 +498,19 @@ impl<'a, 'tcx: 'a> FnCtxtExt<'tcx> for FnCtxtSimulator<'a, 'tcx> { DefId, ); impl<'tcx> TypeVisitor> for FindAmbiguousParameter<'_, 'tcx> { - type BreakTy = ty::GenericArg<'tcx>; - fn visit_ty( - &mut self, - ty: Ty<'tcx>, - ) -> std::ops::ControlFlow { + type Result = ControlFlow>; + fn visit_ty(&mut self, ty: Ty<'tcx>) -> Self::Result { if let Some(origin) = self.0.type_var_origin(ty) && let TypeVariableOriginKind::TypeParameterDefinition(_, def_id) = origin.kind && let generics = self.0.tcx.generics_of(self.1) && let Some(index) = generics.param_def_id_to_index(self.0.tcx, def_id) - && let Some(subst) = + && let Some(arg) = ty::GenericArgs::identity_for_item(self.0.tcx, self.1) .get(index as usize) { - ControlFlow::Break(*subst) + ControlFlow::Break(*arg) } else { ty.super_visit_with(self) } diff --git a/crates/argus/src/rustc/mod.rs b/crates/argus/src/rustc/mod.rs index 0502184..4c78fe1 100644 --- a/crates/argus/src/rustc/mod.rs +++ b/crates/argus/src/rustc/mod.rs @@ -82,7 +82,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { }) } ty::PredicateKind::Subtype(pred) => { - let (a, b) = infcx.instantiate_binder_with_placeholders( + let (a, b) = infcx.enter_forall_and_leak_universe( goal.predicate.kind().rebind((pred.a, pred.b)), ); let expected_found = ExpectedFound::new(true, a, b); @@ -92,7 +92,7 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> { ) } ty::PredicateKind::Coerce(pred) => { - let (a, b) = infcx.instantiate_binder_with_placeholders( + let (a, b) = infcx.enter_forall_and_leak_universe( goal.predicate.kind().rebind((pred.a, pred.b)), ); let expected_found = ExpectedFound::new(false, a, b); diff --git a/crates/argus/src/serialize/path/default.rs b/crates/argus/src/serialize/path/default.rs index 3701bbf..d40a63c 100644 --- a/crates/argus/src/serialize/path/default.rs +++ b/crates/argus/src/serialize/path/default.rs @@ -207,7 +207,7 @@ fn characteristic_def_id_of_type_cached<'a>( characteristic_def_id_of_type_cached(subty, visited) } - ty::RawPtr(mt) => characteristic_def_id_of_type_cached(mt.ty, visited), + ty::RawPtr(ty, _) => characteristic_def_id_of_type_cached(ty, visited), ty::Ref(_, ty, _) => characteristic_def_id_of_type_cached(ty, visited), @@ -220,6 +220,7 @@ fn characteristic_def_id_of_type_cached<'a>( ty::FnDef(def_id, _) | ty::Closure(def_id, _) + | ty::CoroutineClosure(def_id, _) | ty::Coroutine(def_id, _) | ty::CoroutineWitness(def_id, _) | ty::Foreign(def_id) => Some(def_id), diff --git a/crates/argus/src/serialize/term.rs b/crates/argus/src/serialize/term.rs index 0830e38..2d36ab2 100644 --- a/crates/argus/src/serialize/term.rs +++ b/crates/argus/src/serialize/term.rs @@ -287,6 +287,7 @@ pub enum ExprDef<'tcx> { pub enum BinOpDef { Add, AddUnchecked, + Cmp, Sub, SubUnchecked, Mul, diff --git a/crates/argus/src/serialize/ty.rs b/crates/argus/src/serialize/ty.rs index fbffd7b..2f8b810 100644 --- a/crates/argus/src/serialize/ty.rs +++ b/crates/argus/src/serialize/ty.rs @@ -146,6 +146,7 @@ pub enum TyKindDef<'tcx> { Alias(AliasTyKindDef<'tcx>), Dynamic(DynamicTyKindDef<'tcx>), Coroutine(CoroutineTyKindDef<'tcx>), + CoroutineClosure(CoroutineClosureTyKindDef<'tcx>), CoroutineWitness(CoroutineWitnessTyKindDef<'tcx>), } @@ -170,7 +171,10 @@ impl<'tcx> From<&ty::TyKind<'tcx>> for TyKindDef<'tcx> { ty::TyKind::Placeholder(v) => Self::Placeholder(*v), ty::TyKind::Error(_) => Self::Error, ty::TyKind::Infer(v) => Self::Infer(*v), - ty::TyKind::RawPtr(tam) => Self::RawPtr(*tam), + ty::TyKind::RawPtr(ty, mutbl) => Self::RawPtr(ty::TypeAndMut { + ty: *ty, + mutbl: *mutbl, + }), ty::TyKind::Foreign(d) => Self::Foreign(path::PathDefNoArgs::new(*d)), ty::TyKind::Closure(def_id, args) => { Self::Closure(path::PathDefWithArgs::new(*def_id, args)) @@ -187,6 +191,9 @@ impl<'tcx> From<&ty::TyKind<'tcx>> for TyKindDef<'tcx> { ty::TyKind::Coroutine(def_id, args) => { Self::Coroutine(CoroutineTyKindDef::new(*def_id, args)) } + ty::TyKind::CoroutineClosure(def_id, args) => { + Self::CoroutineClosure(CoroutineClosureTyKindDef::new(*def_id, args)) + } ty::TyKind::CoroutineWitness(def_id, args) => { Self::CoroutineWitness(CoroutineWitnessTyKindDef::new(*def_id, args)) } @@ -427,6 +434,57 @@ impl<'tcx> CoroutineTyKindDef<'tcx> { } } +#[derive(Serialize)] +#[serde(rename_all = "camelCase")] +#[cfg_attr(feature = "testing", derive(TS))] +#[cfg_attr(feature = "testing", ts(export, rename = "CoroutineClosureTyKind"))] +pub struct CoroutineClosureTyKindDef<'tcx> { + path: path::PathDefWithArgs<'tcx>, + + #[serde(with = "TyDef")] + #[cfg_attr(feature = "testing", ts(type = "Ty"))] + closure_kind: ty::Ty<'tcx>, + + #[serde(with = "TyDef")] + #[cfg_attr(feature = "testing", ts(type = "Ty"))] + signature_parts: ty::Ty<'tcx>, + + #[serde(with = "TyDef")] + #[cfg_attr(feature = "testing", ts(type = "Ty"))] + upvar_tys: ty::Ty<'tcx>, + + #[serde(with = "TyDef")] + #[cfg_attr(feature = "testing", ts(type = "Ty"))] + captures_by_ref: ty::Ty<'tcx>, + + #[serde(with = "TyDef")] + #[cfg_attr(feature = "testing", ts(type = "Ty"))] + witness: ty::Ty<'tcx>, +} + +impl<'tcx> CoroutineClosureTyKindDef<'tcx> { + pub fn new( + def_id: DefId, + args: &'tcx ty::List>, + ) -> Self { + let closure_kind = args.as_coroutine_closure().kind_ty(); + let signature_parts = args.as_coroutine_closure().signature_parts_ty(); + let upvar_tys = args.as_coroutine_closure().tupled_upvars_ty(); + let captures_by_ref = + args.as_coroutine_closure().coroutine_captures_by_ref_ty(); + let witness = args.as_coroutine_closure().coroutine_witness_ty(); + + Self { + path: path::PathDefWithArgs::new(def_id, &*args), + closure_kind, + signature_parts, + upvar_tys, + captures_by_ref, + witness, + } + } +} + // ----------------------------------- // Coroutine witness definitions @@ -583,7 +641,6 @@ pub enum AbiDef { PtxKernel, Msp430Interrupt, X86Interrupt, - AmdGpuKernel, EfiApi, AvrInterrupt, AvrNonBlockingInterrupt, @@ -592,7 +649,6 @@ pub enum AbiDef { System { unwind: bool }, RustIntrinsic, RustCall, - PlatformIntrinsic, Unadjusted, RustCold, RiscvInterruptM, @@ -779,8 +835,10 @@ pub enum UintTyDef { #[cfg_attr(feature = "testing", derive(TS))] #[cfg_attr(feature = "testing", ts(export, rename = "FloatTy"))] pub enum FloatTyDef { + F16, F32, F64, + F128, } #[derive(Serialize)] @@ -969,6 +1027,9 @@ impl<'tcx> InferTyDef<'tcx> { TypeVariableOrigin, TypeVariableOriginKind::*, }; + // See: `ty_getter` in `printer.ty_infer_name_resolver = Some(Box::new(ty_getter))` + // from: `rustc_infer::infer::error_reporting::need_type_info.rs` + let infcx = get_dynamic_ctx(); let tcx = infcx.tcx; @@ -986,11 +1047,6 @@ impl<'tcx> InferTyDef<'tcx> { .. }) => Self::Named(name, path::PathDefNoArgs::new(def_id)), - Some(TypeVariableOrigin { - kind: OpaqueTypeInference(def_id), - .. - }) => Self::Unnamed(path::PathDefNoArgs::new(def_id)), - Some(TypeVariableOrigin { span, .. }) if !span.is_dummy() => { let span = span.source_callsite(); if let Ok(snippet) = tcx.sess.source_map().span_to_snippet(span) { @@ -1385,9 +1441,9 @@ pub struct TraitPredicateDef<'tcx> { pub trait_ref: TraitRefPrintSugaredDef<'tcx>, - #[serde(with = "ImplPolarityDef")] - #[cfg_attr(feature = "testing", ts(type = "ImplPolarity"))] - pub polarity: ty::ImplPolarity, + #[serde(with = "Polarity")] + #[cfg_attr(feature = "testing", ts(type = "Polarity"))] + pub polarity: ty::PredicatePolarity, } impl<'tcx> TraitPredicateDef<'tcx> { @@ -1465,12 +1521,74 @@ impl<'tcx> TraitRefPrintOnlyTraitPathDef<'tcx> { #[derive(Serialize)] #[cfg_attr(feature = "testing", derive(TS))] -#[cfg_attr(feature = "testing", ts(export, rename = "ImplPolarity"))] -#[serde(remote = "ty::ImplPolarity")] -pub enum ImplPolarityDef { +#[cfg_attr(feature = "testing", ts(export))] +pub enum Polarity { Positive, Negative, - Reservation, + Maybe, +} + +trait PolarityRepresentation { + fn is_positive(&self) -> bool; + fn is_negative(&self) -> bool; +} + +impl From for Polarity { + fn from(value: T) -> Self { + if value.is_positive() { + Self::Positive + } else if value.is_negative() { + Self::Negative + } else { + Self::Maybe + } + } +} + +macro_rules! impl_polarity_repr { + ([$p:ident, $n:ident], $( $t:path ),*) => {$( + impl PolarityRepresentation for $t { + fn is_positive(&self) -> bool { + matches!(self, <$t>::$p) + } + fn is_negative(&self) -> bool { + matches!(self, <$t>::$n) + } + } + + impl PolarityRepresentation for &$t { + fn is_positive(&self) -> bool { + matches!(self, <$t>::$p) + } + fn is_negative(&self) -> bool { + matches!(self, <$t>::$n) + } + } + )*} +} + +impl_polarity_repr! { + [Positive, Negative], + ty::ImplPolarity, + ty::PredicatePolarity +} + +impl Polarity { + fn serialize( + value: impl PolarityRepresentation, + s: S, + ) -> Result + where + S: serde::Serializer, + { + if value.is_positive() { + Self::Positive.serialize(s) + } else if value.is_negative() { + Self::Negative.serialize(s) + } else { + Self::Maybe.serialize(s) + } + } } #[derive(Serialize)] @@ -1661,9 +1779,9 @@ pub struct FnTrait<'tcx> { #[cfg_attr(feature = "testing", derive(TS))] #[cfg_attr(feature = "testing", ts(export))] pub struct Trait<'tcx> { - #[serde(with = "ImplPolarityDef")] - #[cfg_attr(feature = "testing", ts(type = "ImplPolarity"))] - polarity: ty::ImplPolarity, + #[serde(with = "Polarity")] + #[cfg_attr(feature = "testing", ts(type = "Polarity"))] + polarity: ty::PredicatePolarity, #[cfg_attr(feature = "testing", ts(type = "DefinedPath"))] trait_name: TraitRefPrintOnlyTraitPathDef<'tcx>, #[serde(with = "Slice__GenericArgDef")] @@ -1688,10 +1806,10 @@ impl<'tcx> OpaqueImpl<'tcx> { fn insert_trait_and_projection( tcx: ty::TyCtxt<'tcx>, trait_ref: ty::PolyTraitRef<'tcx>, - polarity: ty::ImplPolarity, + polarity: ty::PredicatePolarity, proj_ty: Option<(DefId, ty::Binder<'tcx, ty::Term<'tcx>>)>, traits: &mut FxIndexMap< - (ty::PolyTraitRef<'tcx>, ty::ImplPolarity), + (ty::PolyTraitRef<'tcx>, ty::PredicatePolarity), FxIndexMap>>, >, fn_traits: &mut FxIndexMap, OpaqueFnEntry<'tcx>>, @@ -1701,7 +1819,7 @@ impl<'tcx> OpaqueImpl<'tcx> { // If our trait_ref is FnOnce or any of its children, project it onto the parent FnOnce // super-trait ref and record it there. // We skip negative Fn* bounds since they can't use parenthetical notation anyway. - if polarity == ty::ImplPolarity::Positive + if polarity == ty::PredicatePolarity::Positive && let Some(fn_once_trait) = tcx.lang_items().fn_once_trait() { // If we have a FnOnce, then insert it into @@ -1789,11 +1907,13 @@ impl<'tcx> OpaqueImpl<'tcx> { // Don't print `+ Sized`, but rather `+ ?Sized` if absent. if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() { match pred.polarity { - ty::ImplPolarity::Positive | ty::ImplPolarity::Reservation => { + ty::PredicatePolarity::Positive => { has_sized_bound = true; continue; } - ty::ImplPolarity::Negative => has_negative_sized_bound = true, + ty::PredicatePolarity::Negative => { + has_negative_sized_bound = true + } } } @@ -1816,7 +1936,7 @@ impl<'tcx> OpaqueImpl<'tcx> { Self::insert_trait_and_projection( tcx, trait_ref, - ty::ImplPolarity::Positive, + ty::PredicatePolarity::Positive, Some(proj_ty), &mut traits, &mut fn_traits, @@ -1868,7 +1988,7 @@ impl<'tcx> OpaqueImpl<'tcx> { _ => { if entry.has_fn_once { traits - .entry((fn_once_trait_ref, ty::ImplPolarity::Positive)) + .entry((fn_once_trait_ref, ty::PredicatePolarity::Positive)) .or_default() .extend( // Group the return ty with its def id, if we had one. @@ -1879,12 +1999,12 @@ impl<'tcx> OpaqueImpl<'tcx> { } if let Some(trait_ref) = entry.fn_mut_trait_ref { traits - .entry((trait_ref, ty::ImplPolarity::Positive)) + .entry((trait_ref, ty::PredicatePolarity::Positive)) .or_default(); } if let Some(trait_ref) = entry.fn_trait_ref { traits - .entry((trait_ref, ty::ImplPolarity::Positive)) + .entry((trait_ref, ty::PredicatePolarity::Positive)) .or_default(); } } diff --git a/crates/argus/src/test_utils.rs b/crates/argus/src/test_utils.rs index 3ced6de..3c5a402 100644 --- a/crates/argus/src/test_utils.rs +++ b/crates/argus/src/test_utils.rs @@ -243,8 +243,12 @@ where Cb: FnOnce(TyCtxt<'_>), { fn config(&mut self, config: &mut rustc_interface::Config) { - config.parse_sess_created = Some(Box::new(|sess| { - sess.dcx = DiagCtxt::with_emitter(SilentEmitter::boxed()); + config.psess_created = Some(Box::new(|sess| { + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); + sess.dcx.make_silent(fallback_bundle, None, false); })); } diff --git a/crates/argus/src/types.rs b/crates/argus/src/types.rs index 5f120b5..67914fb 100644 --- a/crates/argus/src/types.rs +++ b/crates/argus/src/types.rs @@ -26,7 +26,7 @@ use crate::{ safe::{PathDefNoArgs, TraitRefPrintOnlyTraitPathDef}, serialize_to_value, ty::{ - ImplPolarityDef, RegionDef, Slice__ClauseDef, Slice__GenericArgDef, + Polarity, RegionDef, Slice__ClauseDef, Slice__GenericArgDef, Slice__TyDef, TyDef, }, }, @@ -310,9 +310,7 @@ pub struct ClauseWithBounds<'tcx> { #[cfg_attr(feature = "testing", ts(export))] pub enum ClauseBound<'tcx> { Trait( - #[serde(with = "ImplPolarityDef")] - #[cfg_attr(feature = "testing", ts(type = "ImplPolarity"))] - ty::ImplPolarity, + Polarity, #[cfg_attr(feature = "testing", ts(type = "TraitRefPrintOnlyTraitPath"))] TraitRefPrintOnlyTraitPathDef<'tcx>, ), @@ -564,7 +562,7 @@ pub(super) mod intermediate { ) -> Result { let string = match value { Ok(Certainty::Yes) => "yes", - Ok(Certainty::Maybe(MaybeCause::Overflow)) => "maybe-overflow", + Ok(Certainty::Maybe(MaybeCause::Overflow { .. })) => "maybe-overflow", Ok(Certainty::Maybe(MaybeCause::Ambiguity)) => "maybe-ambiguity", Err(..) => "no", }; diff --git a/crates/argus_cli/src/plugin.rs b/crates/argus_cli/src/plugin.rs index c836839..41fa535 100644 --- a/crates/argus_cli/src/plugin.rs +++ b/crates/argus_cli/src/plugin.rs @@ -275,18 +275,12 @@ impl Option> rustc_driver::Callbacks for ArgusCallbacks { fn config(&mut self, config: &mut rustc_interface::Config) { - config.parse_sess_created = Some(Box::new(|sess| { - // // Create a new emitter writer which consumes *silently* all - // // errors. There most certainly is a *better* way to do this, - // // if you, the reader, know what that is, please open an issue :) - // let fallback_bundle = rustc_errors::fallback_fluent_bundle( - // rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), - // false, - // ); - // let emitter = HumanEmitter::new(Box::new(io::sink()), fallback_bundle); - // sess.dcx = DiagCtxt::with_emitter(Box::new(emitter)); - - sess.dcx = DiagCtxt::with_emitter(SilentEmitter::boxed()); + config.psess_created = Some(Box::new(|sess| { + let fallback_bundle = rustc_errors::fallback_fluent_bundle( + rustc_driver::DEFAULT_LOCALE_RESOURCES.to_vec(), + false, + ); + sess.dcx.make_silent(fallback_bundle, None, false); })); } diff --git a/ide/packages/panoptes/src/print/private/argus.tsx b/ide/packages/panoptes/src/print/private/argus.tsx index 7f2725b..a87c46b 100644 --- a/ide/packages/panoptes/src/print/private/argus.tsx +++ b/ide/packages/panoptes/src/print/private/argus.tsx @@ -13,7 +13,7 @@ import { anyElems } from "../../utilities/func"; import { PrintDefPath } from "./path"; import { PrintClause } from "./predicate"; import { Angled, CommaSeparated, Kw, PlusSeparated } from "./syntax"; -import { PrintGenericArg, PrintImplPolarity, PrintRegion, PrintTy } from "./ty"; +import { PrintGenericArg, PrintPolarity, PrintRegion, PrintTy } from "./ty"; export const PrintImplHeader = ({ o }: { o: ImplHeader }) => { console.debug("Printing ImplHeader", o); @@ -117,7 +117,7 @@ const PrintClauseBound = ({ o }: { o: ClauseBound }) => { const [polarity, path] = o.Trait; return ( <> - + ); diff --git a/ide/packages/panoptes/src/print/private/hir.css b/ide/packages/panoptes/src/print/private/hir.css deleted file mode 100644 index ac6b4ca..0000000 --- a/ide/packages/panoptes/src/print/private/hir.css +++ /dev/null @@ -1,16 +0,0 @@ -.WhereConstraintArea { - display: flex; - flex-direction: column; - padding: 0.25em; -} - -span.where { - padding: 0.15em; - border: 1px solid var(--vscode-widget-border); - border-radius: 5px; -} - -span.where:hover { - font-weight: bold; - opacity: 0.75; -} \ No newline at end of file diff --git a/ide/packages/panoptes/src/print/private/hir.tsx b/ide/packages/panoptes/src/print/private/hir.tsx deleted file mode 100644 index ebd204c..0000000 --- a/ide/packages/panoptes/src/print/private/hir.tsx +++ /dev/null @@ -1,661 +0,0 @@ -// import { -// AnonConst, -// GenericArgs, -// GenericBound, -// GenericParam, -// Generics, -// Ident, -// Impl, -// Lifetime, -// MutTy, -// Mutability, -// ParamName, -// Path, -// PathSegment, -// PolyTraitRef, -// QPath, -// Symbol, -// Term, -// TraitRef, -// Ty, -// TyKind, -// TypeBinding, -// } from "@argus/common/bindings"; -// import _ from "lodash"; -// import React from "react"; - -// import { HoverInfo } from "../../HoverInfo"; -// import { Toggle } from "../../Toggle"; -// import "./hir.css"; -// import * as kw from "./syntax"; -// import { Kw } from "./syntax"; - -// function isObject(x: any): x is object { -// return typeof x === "object" && x !== null; -// } - -// const genericArgsNone: GenericArgs = { -// args: [], -// bindings: [], -// parenthesized: "No", -// }; - -// const CommaSeparated = ({ children }: React.PropsWithChildren) => { -// return ( -// -// {React.Children.map(children, (child, i) => ( -// -// {i > 0 ? ", " : ""} -// {child} -// -// ))} -// -// ); -// }; - -// const Angled = ({ children }: React.PropsWithChildren) => { -// const [lt, gt] = ["<", ">"]; -// return ( -// -// {lt} -// {children} -// {gt} -// -// ); -// }; - -// function paramName(param: ParamName): Ident { -// return param === "Error" || param === "Fresh" -// ? kw.UnderscoreLifetime -// : param.Plain; -// } - -// export const PrintImpl = ({ impl }: { impl: Impl }) => { -// console.debug("Printing Impl", impl); - -// const generics = -// impl.generics.params.length === 0 ? null : ( -// -// {" "} -// -// ); - -// const polarity = impl.polarity === "Positive" ? null : "!"; - -// const ofTrait = -// impl.of_trait !== undefined ? ( -// -// for{" "} -// -// ) : null; - -// return ( -// -// impl -// {generics} -// {polarity} -// {ofTrait} -// -// -// -// ); -// }; - -// const PrintWhereClause = ({ generics }: { generics: Generics }) => { -// if (generics.predicates.length === 0) { -// return ""; -// } - -// const whereHoverContent = () => ( -//
-// {_.map(generics.predicates, (pred, idx) => { -// const innerContent = -// "BoundPredicate" in pred ? ( -// -// -// -// -// -// ) : "RegionPredicate" in pred ? ( -// -// : -// {_.map(pred.RegionPredicate.bounds, (bound, idx) => -// "Outlives" in bound ? ( -// -// ) : ( -// "ERROR UNKNOWN" -// ) -// )} -// -// ) : "EqPredicate" in pred ? ( -// -// ={" "} -// -// -// ) : ( -// "" -// ); - -// return ( -//
-// {innerContent} -//
-// ); -// })} -//
-// ); - -// return ( -// -// {" "} -// where{" "} -// -// ... -// -// -// ); -// }; - -// const PrintGenericsParams = ({ generics }: { generics: Generics }) => { -// const params = generics.params; -// if (params.length == 0) { -// return ""; -// } - -// const innerElems = _.map(params, (param, idx) => ( -// -// )); - -// return ( -// -// {innerElems}} -// /> -// -// ); -// }; - -// const PrintGenericParam = ({ param }: { param: GenericParam }) => { -// const prefix = "Const" in param.kind ? "const " : ""; -// const ident = ; -// const after = -// "Lifetime" in param.kind ? ( -// "" -// ) : "Type" in param.kind && param.kind.Type.default !== undefined ? ( -// -// {" = "} -// {} -// -// ) : "Const" in param.kind ? ( -// -// {": "} -// -// {param.kind.Const.default !== undefined ? ( -// -// {" = "} -// -// -// ) : ( -// "" -// )} -// -// ) : ( -// "" -// ); - -// return ( -// -// {prefix} -// {ident} -// {after} -// -// ); -// }; - -// const PrintAnonConst = ({ anon }: { anon: AnonConst }) => { -// return "TODO: anonconst"; -// }; - -// const PrintIdent = ({ ident }: { ident: Ident }) => { -// return {ident.name}; -// }; - -// const PrintTraitRef = ({ traitRef }: { traitRef: TraitRef }) => { -// return ; -// }; - -// const PrintPath = ({ -// path, -// colonsBefore = false, -// }: { -// path: Path; -// colonsBefore?: boolean; -// }) => { -// return ( -// -// {_.map(path.segments, (segment, idx) => ( -// -// {idx > 0 ? "::" : ""} -// {segment.ident !== kw.PathRoot ? ( -// <> -// -// -// -// ) : ( -// "" -// )} -// -// ))} -// -// ); -// }; - -// function genericArgsInputs(args: GenericArgs): Ty[] | undefined { -// if (args.parenthesized !== "ParenSugar") { -// return; -// } - -// for (let arg of args.args) { -// if ("Type" in arg && isObject(arg.Type.kind) && "Tup" in arg.Type.kind) { -// return arg.Type.kind.Tup; -// } -// } -// } - -// function genericArgsReturn(args: GenericArgs): Ty | undefined { -// const bk = _.first(args.bindings)?.kind; -// if (bk !== undefined && "Equality" in bk) { -// if ("Ty" in bk.Equality.term) { -// return bk.Equality.term.Ty; -// } -// } -// } - -// const PrintGenericArgs = ({ -// args, -// colonBefore, -// }: { -// args: GenericArgs | undefined; -// colonBefore: boolean; -// }) => { -// const uArgs = args ?? genericArgsNone; - -// switch (uArgs.parenthesized) { -// case "No": { -// // SEE: https://github.com/rust-lang/rust/blob/0ea334ab739265168fba366afcdc7ff68c1dec53/compiler/rustc_hir_pretty/src/lib.rs#L1620 -// const start = colonBefore ? "::<" : "<"; -// let empty = true; -// // TODO: wtf is this???? -// const startOrComma = () => { -// if (empty) { -// empty = false; -// return start; -// } else { -// return ", "; -// } -// }; - -// // SEE https://github.com/rust-lang/rust/blob/0ea334ab739265168fba366afcdc7ff68c1dec53/compiler/rustc_hir_pretty/src/lib.rs#L1632-L1643 -// // for when we want to make eliding arguments possible. -// let nonelidedGenericArgs = uArgs.args.length > 0; - -// let nonElided = !nonelidedGenericArgs -// ? "" -// : (() => { -// const prefix = startOrComma(); -// const commsep = ( -// { -// if ("Lifetime" in genA) { -// return ; -// } else if ("Type" in genA) { -// return ; -// } else if ("Const" in genA) { -// return ; -// } else if ("Infer" in genA) { -// return "_"; -// } -// })} -// /> -// ); -// return ( -// -// {prefix} -// {commsep} -// -// ); -// })(); - -// const bindings = _.map(uArgs.bindings, (binding, idx) => ( -// -// {startOrComma()} -// -// -// )); - -// const end = empty ? "" : ">"; - -// return ( -// -// {nonElided} -// {bindings} -// {end} -// -// ); -// } -// case "ParenSugar": { -// const inputs = genericArgsInputs(uArgs); -// const argList = ( -// -// ( -// ( -// -// ))} -// /> -// ) -// -// ); -// const arr = " -> "; -// const ret = ; - -// return ( -// -// {argList} -// {arr} -// {ret} -// -// ); -// } -// case "ReturnTypeNotation": { -// return "(..)"; -// } -// } -// }; - -// const PrintTerm = ({ term }: { term: Term }) => { -// if ("Ty" in term) { -// return ; -// } else if ("Const" in term) { -// return ; -// } -// }; - -// const PrintBounds = ({ -// prefix, -// bounds, -// }: { -// prefix: string; -// bounds: GenericBound[]; -// }) => { -// return ( -// -// {_.map(bounds, (bound, idx) => { -// const prfx = idx == 0 ? (prefix.length > 0 ? prefix + " " : "") : "+ "; -// if ("Trait" in bound) { -// const mb = bound.Trait[1] === "Maybe" ? "?" : ""; -// return ( -// -// {prfx} -// {mb} -// -// -// ); -// } else if ("Outlives" in bound) { -// return ( -// -// {prfx} -// -// -// ); -// } -// })} -// -// ); -// }; - -// const PrintPolyTraitRef = ({ pTraitRef }: { pTraitRef: PolyTraitRef }) => { -// return ( -// <> -// -// -// -// ); -// }; - -// const PrintFormalGenericParams = ({ params }: { params: GenericParam[] }) => { -// if (params.length === 0) { -// return ""; -// } - -// return ( -// -// for -// -// -// ); -// }; - -// const PrintGenericParams = ({ params }: { params: GenericParam[] }) => { -// if (params.length == 0) { -// return ""; -// } -// const inner = ( -// ( -// -// ))} -// /> -// ); -// return {inner}; -// }; - -// const PrintTypeBinding = ({ binding }: { binding: TypeBinding }) => { -// const id = ; -// const genArgs = ( -// -// ); -// const rest = -// "Equality" in binding.kind ? ( -// -// {"= "} -// -// -// ) : "Constraint" in binding.kind ? ( -// -// ) : ( -// "" -// ); -// return ( -// -// {id} -// {genArgs} {rest} -// -// ); -// }; - -// const PrintTy = ({ ty }: { ty: Ty }) => { -// return ; -// }; - -// const PrintTyKind = ({ tyKind }: { tyKind: TyKind }) => { -// if (tyKind === "Never") { -// return "!"; -// } else if (tyKind === "Infer") { -// return "_"; -// } else if (tyKind === "Err") { -// return "/*ERROR*/"; -// } else if ("InferDelegation" in tyKind) { -// return "_"; -// } else if ("Slice" in tyKind) { -// return ( -// -// [] -// -// ); -// } else if ("Ptr" in tyKind) { -// return ( -// -// * -// -// ); -// } else if ("Ref" in tyKind) { -// const [lifetime, ty] = tyKind.Ref; -// return ( -// -// & -// -// -// ); -// } else if ("Tup" in tyKind) { -// return ( -// ( -// -// ))} -// /> -// ); -// } else if ("BareFn" in tyKind) { -// return "TODO: BAREFN"; -// } else if ("OpaqueDef" in tyKind) { -// return "TODO: OPAQUEDEF"; -// } else if ("Path" in tyKind) { -// return ; -// } else if ("TraitObject" in tyKind) { -// return "TODO: TRAITOBJECT"; -// } else if ("Array" in tyKind) { -// return "TODO: ARRAY"; -// } else if ("Typeof" in tyKind) { -// return ( -// -// typeof -// -// ); -// } -// }; - -// const PrintMutTy = ({ -// mty, -// printConst = true, -// }: { -// mty: MutTy; -// printConst?: boolean; -// }) => { -// return ( -// <> -// -// -// -// ); -// }; - -// const PrintMutability = ({ -// mtbl, -// printConst, -// }: { -// mtbl: Mutability; -// printConst: boolean; -// }) => { -// return mtbl === "Mut" ? "mut " : printConst ? "const " : ""; -// }; - -// const PrintLifetime = ({ lifetime }: { lifetime: Lifetime }) => { -// return ; -// }; - -// const PrintQPath = ({ -// qpath, -// colonsBefore, -// }: { -// qpath: QPath; -// colonsBefore: boolean; -// }) => { -// if ("LangItem" === qpath) { -// return "#[lang = (...)]"; -// } else if ("Resolved" in qpath && qpath.Resolved[0] === null) { -// return ; -// } else if ("Resolved" in qpath && qpath.Resolved[0] !== null) { -// const [ty, path] = qpath.Resolved; -// const inner = ( -// -// -// {" as "} -// -// ); -// const listed = _.map(path.segments.slice(-1), (seg, idx) => { -// const prefix = idx > 0 ? "::" : ""; -// return ( -// -// {prefix} -// -// -// ); -// }); -// const angles = ( -// -// -// {inner} -// {listed} -// -// -// ); -// const lastSegment = ( -// -// ); -// return ( -// -// {angles}::{lastSegment} -// -// ); -// } else if ("TypeRelative" in qpath) { -// const [ty, segment] = qpath.TypeRelative; -// // FIXME: woof ... -// const prefix = -// isObject(ty.kind) && -// "Path" in ty.kind && -// isObject(ty.kind.Path) && -// "Resolved" in ty.kind.Path && -// ty.kind.Path.Resolved[0] === undefined ? ( -// -// ) : ( -// -// -// -// ); -// return ( -// -// {prefix}:: -// -// -// ); -// } -// }; - -// const PrintPathSegment = ({ -// segment, -// colonsBefore = false, -// }: { -// segment: PathSegment; -// colonsBefore?: boolean; -// }) => { -// if (segment.ident === kw.PathRoot) { -// return ""; -// } - -// return ( -// <> -// -// -// -// ); -// }; diff --git a/ide/packages/panoptes/src/print/private/predicate.tsx b/ide/packages/panoptes/src/print/private/predicate.tsx index d9d6c3b..757586d 100644 --- a/ide/packages/panoptes/src/print/private/predicate.tsx +++ b/ide/packages/panoptes/src/print/private/predicate.tsx @@ -24,7 +24,7 @@ import { PrintAliasTy, PrintBinder, PrintGenericArg, - PrintImplPolarity, + PrintPolarity, PrintRegion, PrintTy, } from "./ty"; @@ -199,7 +199,7 @@ export const PrintTraitPredicate = ({ o }: { o: TraitPredicate }) => { return ( <> : - + ); diff --git a/ide/packages/panoptes/src/print/private/term.tsx b/ide/packages/panoptes/src/print/private/term.tsx index f833deb..b7d6856 100644 --- a/ide/packages/panoptes/src/print/private/term.tsx +++ b/ide/packages/panoptes/src/print/private/term.tsx @@ -36,7 +36,15 @@ export const PrintTerm = ({ o }: { o: Term }) => { export const PrintExpr = ({ o }: { o: ExprDef }) => { if ("Binop" in o) { const [op, lhs, rhs] = o.Binop; - return ( + return op === "Cmp" ? ( + <> + + .cmp + + + + + ) : ( <> @@ -71,7 +79,9 @@ export const PrintExpr = ({ o }: { o: ExprDef }) => { } }; -const PrintBinOp = ({ o }: { o: BinOp }) => { +// NOTE: this is the mir BinOp enum so not all operators are "source representable." +// Exluding "Cmp" as it rearranges the operands and doesn't follow the pattern. +const PrintBinOp = ({ o }: { o: Exclude }) => { if (o === "Add") { return "+"; } else if (o === "AddUnchecked") { diff --git a/ide/packages/panoptes/src/print/private/ty.tsx b/ide/packages/panoptes/src/print/private/ty.tsx index c77adeb..79817e9 100644 --- a/ide/packages/panoptes/src/print/private/ty.tsx +++ b/ide/packages/panoptes/src/print/private/ty.tsx @@ -5,6 +5,7 @@ import { AssocItem, BoundTy, BoundVariable, + CoroutineClosureTyKind, CoroutineTyKind, CoroutineWitnessTyKind, DynamicTyKind, @@ -13,12 +14,12 @@ import { FnSig, FnTrait, GenericArg, - ImplPolarity, InferTy, IntTy, OpaqueImpl, ParamTy, PlaceholderBoundTy, + Polarity, PolyExistentialPredicates, PolyFnSig, Region, @@ -131,6 +132,8 @@ export const PrintTyKind = ({ o }: { o: TyKind }) => { return ; } else if ("Closure" in o) { return ; + } else if ("CoroutineClosure" in o) { + return ; } else if ("Param" in o) { return ; } else if ("Bound" in o) { @@ -164,6 +167,15 @@ export const PrintCoroutineTy = ({ o }: { o: CoroutineTyKind }) => { ); }; +export const PrintCoroutineClosureTy = ({ + o, +}: { + o: CoroutineClosureTyKind; +}) => { + // TODO: we can print other things known to the closure, like kind, signature, upvars, etc. + return ; +}; + export const PrintCoroutineWitnessTy = ({ o, }: { @@ -440,8 +452,8 @@ export const PrintBoundVariable = ({ o }: { o: BoundVariable }) => { } }; -export const PrintImplPolarity = ({ o }: { o: ImplPolarity }) => { - return o === "Negative" ? "!" : null; +export const PrintPolarity = ({ o }: { o: Polarity }) => { + return o === "Negative" ? "!" : o === "Maybe" ? "?" : null; }; export const PrintOpaqueImplType = ({ o }: { o: OpaqueImpl }) => { @@ -478,7 +490,7 @@ export const PrintOpaqueImplType = ({ o }: { o: OpaqueImpl }) => { const PrintTrait = ({ o }: { o: Trait }) => { console.debug("Printing Trait", o); - const prefix = ; + const prefix = ; const name = ; const ownArgs = _.map(o.ownArgs, arg => () => ); const assocArgs = _.map(o.assocArgs, arg => () => ( diff --git a/rust-toolchain.toml b/rust-toolchain.toml index 3d17d42..307f219 100644 --- a/rust-toolchain.toml +++ b/rust-toolchain.toml @@ -1,3 +1,3 @@ [toolchain] -channel = "nightly-2024-01-24" +channel = "nightly-2024-04-08" components = ["rust-src", "rustc-dev", "llvm-tools-preview"]