From ac2b8f86433dca3876551ebfe138c766a38367b6 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 17 Sep 2024 22:36:05 +0200 Subject: [PATCH 1/2] Fix missing occurence check --- .../src/ty/trait_resolution/proof_forest.rs | 7 ++++-- .../ty/trait_bound/occurence_check.fe | 23 +++++++++++++++++++ .../ty/trait_bound/occurence_check.snap | 13 +++++++++++ 3 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 crates/uitest/fixtures/ty/trait_bound/occurence_check.fe create mode 100644 crates/uitest/fixtures/ty/trait_bound/occurence_check.snap diff --git a/crates/hir-analysis/src/ty/trait_resolution/proof_forest.rs b/crates/hir-analysis/src/ty/trait_resolution/proof_forest.rs index 2035afcdc..f4cc301a0 100644 --- a/crates/hir-analysis/src/ty/trait_resolution/proof_forest.rs +++ b/crates/hir-analysis/src/ty/trait_resolution/proof_forest.rs @@ -466,8 +466,11 @@ impl ConsumerNode { let (pending_inst, canonicalized_pending_inst) = &c_node.query; let solution = canonicalized_pending_inst.extract_solution(&mut table, solution); - // Unifies pending inst and solution. - table.unify(*pending_inst, solution).unwrap(); + // Try to unifies pending inst and solution. + if table.unify(*pending_inst, solution).is_err() { + return true; + } + let tree_root = c_node.root; if c_node.remaining_goals.is_empty() { diff --git a/crates/uitest/fixtures/ty/trait_bound/occurence_check.fe b/crates/uitest/fixtures/ty/trait_bound/occurence_check.fe new file mode 100644 index 000000000..ffed2641d --- /dev/null +++ b/crates/uitest/fixtures/ty/trait_bound/occurence_check.fe @@ -0,0 +1,23 @@ +trait Trait1 { + fn f(self:Self) +} + +trait Trait2 {} + +struct Memory { + x: i32, +} + +impl Trait2>>> for Memory { } + +impl Trait1 for Memory>> +where T: Trait1, + U: Trait2 +{ + fn f(self: Self) {} +} + +fn g(y: T) { + let x: Memory>> + x.f() +} diff --git a/crates/uitest/fixtures/ty/trait_bound/occurence_check.snap b/crates/uitest/fixtures/ty/trait_bound/occurence_check.snap new file mode 100644 index 000000000..2a343d569 --- /dev/null +++ b/crates/uitest/fixtures/ty/trait_bound/occurence_check.snap @@ -0,0 +1,13 @@ +--- +source: crates/uitest/tests/ty.rs +expression: diags +input_file: crates/uitest/fixtures/ty/trait_bound/occurence_check.fe +--- +error[6-0003]: trait bound is not satisfied + ┌─ occurence_check.fe:22:7 + │ +22 │ x.f() + │ ^ + │ │ + │ `Memory>>` doesn't implement `Trait1` + │ trait bound `T: Trait2<_>` is not satisfied From 7e9d00ded7c97a79379874125c90c7225ef62099 Mon Sep 17 00:00:00 2001 From: Yoshitomo Nakanishi Date: Tue, 17 Sep 2024 22:46:01 +0200 Subject: [PATCH 2/2] Make clippy happy --- crates/codegen/src/yul/isel/inst_order.rs | 14 +++++++------- crates/hir-analysis/src/ty/def_analysis.rs | 1 + 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/crates/codegen/src/yul/isel/inst_order.rs b/crates/codegen/src/yul/isel/inst_order.rs index afc82f001..b4bdf32a0 100644 --- a/crates/codegen/src/yul/isel/inst_order.rs +++ b/crates/codegen/src/yul/isel/inst_order.rs @@ -464,13 +464,13 @@ impl<'a> InstSerializer<'a> { /// /// The scoring function `F` is defined as follows: /// 1. The initial score of each candidate('cand_bb`) is number of - /// predecessors of the candidate. + /// predecessors of the candidate. /// /// 2. Find the `top_cand` of each `cand_bb`. `top_cand` can be found by - /// [`Self::try_find_top_cand`] method, see the method for details. + /// [`Self::try_find_top_cand`] method, see the method for details. /// /// 3. If `top_cand` is found, then add the `cand_bb` score to the - /// `top_cand` score, then set 0 to the `cand_bb` score. + /// `top_cand` score, then set 0 to the `cand_bb` score. /// /// After the scoring, the candidates with the highest score will be /// selected. @@ -516,16 +516,16 @@ impl<'a> InstSerializer<'a> { /// A `top_cand` can be found by the following rules: /// /// 1. Find the block which is contained in DF of `cand_bb` and in - /// `cands_with_score`. + /// `cands_with_score`. /// /// 2. If a block is found in 1., and the score of the block is positive, - /// then the block is `top_cand`. + /// then the block is `top_cand`. /// /// 2'. If a block is found in 1., and the score of the block is 0, then the - /// `top_cand` of the block is `top_cand` of `cand_bb`. + /// `top_cand` of the block is `top_cand` of `cand_bb`. /// /// 2''. If a block is NOT found in 1., then there is no `top_cand` for - /// `cand_bb`. + /// `cand_bb`. fn try_find_top_cand( &self, cands_with_score: &IndexMap, diff --git a/crates/hir-analysis/src/ty/def_analysis.rs b/crates/hir-analysis/src/ty/def_analysis.rs index 0b994338e..5226a6acd 100644 --- a/crates/hir-analysis/src/ty/def_analysis.rs +++ b/crates/hir-analysis/src/ty/def_analysis.rs @@ -284,6 +284,7 @@ impl<'db> DefAnalyzer<'db> { /// This method verifies if /// 1. the given `ty` has `*` kind. /// 2. the given `ty` is not const type + /// /// TODO: This method is a stop-gap implementation until we design a true /// const type system. fn verify_term_type_kind(&mut self, ty: HirTyId<'db>, span: DynLazySpan<'db>) -> bool {