Skip to content

Fix wire type matching to only allow conversions the compiler actually makes - #4688

Open
Keavon wants to merge 3 commits into
masterfrom
input-adapter-conversion-table
Open

Keavon wants to merge 3 commits into
masterfrom
input-adapter-conversion-table

Conversation

@Keavon

@Keavon Keavon commented Oct 13, 2026 •

Copy link
Copy Markdown
Member

Follow-up to #4670. When you hover a node with a wire, it reveals hidden inputs based on a type check that didn't match what the compiler does, so it got things wrong in both directions:

  • It assumed every ranked input converts through its element's input_adapter. The preprocessor only puts one in front of inputs registered with a single ranked type. So a Color wire was treated as fitting inputs like Fill's Content, and that fails to compile once connected. Now the editor asks the preprocessor (input_adapter_identifier, the same function it uses itself) which adapter each input gets, and allows only that adapter's conversions.
  • It ignored rank promotions, so an item wire going into a list input was rejected even though type resolution handles that case. The promotion rules moved into Promotion::between, and both the compiler and the editor use it now.
  • A subgraph import that feeds a Monitor first (like in Path) accepted nearly any type, because Monitor is generic. Nodes that pass their input type through unchanged are now looked through, and what they feed decides what the import accepts.

One example of something this fixes from #4670 is the case of dragging a Vector wire over a Fill or Stroke node which should expand the node to show the Paint parameter. It should work equally for both, as they're both valid. But as of #4670, it only the Fill node works and the Stroke node doesn't expand to offer it, which this followup PR fixes. It also fixes a number of misleading and broken type details across the tooltips, such as the Path node's primary input showing the entire set of all inputs accepted by the Monitor node (essentially all wire types, which the tooltip can't hope to fit on screen).

@Keavon
Keavon requested a review from TrueDoctor as a code owner October 13, 2026 09:33
@TrueDoctor

Copy link
Copy Markdown
Member

I deliberatly choose not to implement this in my pr because dealing with rank promotions is very ugly, I will need time to review this in detail since it touches the compiler and type resolution so you may not merge this on your own

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 issue found across 6 files

Confidence score: 3/5

  • In editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs, treating every subgraph export as unconstrained can allow a wire that its parent-side consumers reject. Resolve the export against its downstream output constraint.
Prompt for AI agents (unresolved issues)

Check if these issues are valid — if so, understand the root cause of each and fix them. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. If appropriate, use sub-agents to investigate and fix each issue separately.


<file name="editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs">

<violation number="1" location="editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs:409">
P2: This treats every subgraph export as unconstrained, so a wire passed through a subgraph can be accepted even when its parent-side consumers reject that type. Resolve the export against its downstream output constraints before accepting it.</violation>
</file>

Reply with feedback, questions, or to request a fix.

Re-trigger cubic

fn type_acceptor(&self, input_connector: &InputConnector, network_path: &[NodeId]) -> Box<dyn Fn(&Type) -> bool> {
let accepts_here: Box<dyn Fn(&Type) -> bool> = match input_connector {
// An export can have any type connected to it
InputConnector::Export(_) => Box::new(|_| true),

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2: This treats every subgraph export as unconstrained, so a wire passed through a subgraph can be accepted even when its parent-side consumers reject that type. Resolve the export against its downstream output constraints before accepting it.

Prompt for AI agents
Check if this issue is valid — if so, understand the root cause and fix it. When an issue isn't valid or won't be fixed in this PR, reply in its thread with the reason and then resolve the thread. At editor/src/messages/portfolio/document/utility_types/network_interface/resolved_types.rs, line 409:

<comment>This treats every subgraph export as unconstrained, so a wire passed through a subgraph can be accepted even when its parent-side consumers reject that type. Resolve the export against its downstream output constraints before accepting it.</comment>

<file context>
@@ -319,6 +373,114 @@ impl NodeNetworkInterface {
+	fn type_acceptor(&self, input_connector: &InputConnector, network_path: &[NodeId]) -> Box<dyn Fn(&Type) -> bool> {
+		let accepts_here: Box<dyn Fn(&Type) -> bool> = match input_connector {
+			// An export can have any type connected to it
+			InputConnector::Export(_) => Box::new(|_| true),
+			InputConnector::Node { node_id, input_index } => match self.implementation(node_id, network_path) {
+				Some(DocumentNodeImplementation::ProtoNode(proto_node_identifier)) => {
</file context>

This branch was successfully deployed

1 active deployment
graphite-dev (Preview) — 46b66167 Deployed Oct 13, 2026 by github-actions[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants