Skip to content
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
32 changes: 31 additions & 1 deletion src/v1/04_infer.dag
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@ import v1.compiler.infer_resolve {
import v1.compiler.infer_sigs {
ResolvedFuncSig, ResolvedFuncEnv, ResolveFuncSigsResult,
resolve_func_sigs, flatten_parent_envs,
FuncSigLookup, FuncSigResolved, FuncSigUnresolved, FuncSigAmbiguous
FuncSigLookup, FuncSigResolved, FuncSigUnresolved, FuncSigAmbiguous, FuncSigCallerNotAdmitted
}
import v1.compiler.infer_emit_info {
TypeRepr, StructRepr, EnumRepr,
Expand Down Expand Up @@ -2747,6 +2747,21 @@ fn infer_expr_body(texpr: Node, scope: InferScope, expected: Node?) -> InferResu
}
FuncSigAmbiguous { candidates: ambiguous_fn_candidates } =>
ambiguous_reference_refusal(name: name, candidates: ambiguous_fn_candidates, span: span, scope: scope)
FuncSigCallerNotAdmitted { function_name: fname, owner_module_path: om, admitted: adm } =>
InferResult {
typed: semantic_expr_error_node(message: concat("constructor call admission refused for '", fname, "'"), span: span),
diagnostics: [make_error_node(
diagnostic: ConstructorCallAdmissionRefused {
constructor_module_path: om,
constructor_decl_name: fname,
caller_module_path: scope.module_name,
caller_decl_name: if scope.caller_decl_name == "" { "<unknown>" } else { scope.caller_decl_name },
permitted_callers: adm,
span: span
},
module_name: scope.module_name
)]
}
FuncSigUnresolved =>
match lookup_binding_by_name(env: scope.type_env, name: name) {
Present { value: gbinding } =>
Expand Down Expand Up @@ -2921,6 +2936,21 @@ fn infer_expr_body(texpr: Node, scope: InferScope, expected: Node?) -> InferResu
match call_sig_lookup {
FuncSigAmbiguous { candidates: ambiguous_fn_candidates } =>
ambiguous_reference_refusal(name: func_name, candidates: ambiguous_fn_candidates, span: span, scope: scope)
FuncSigCallerNotAdmitted { function_name: fname, owner_module_path: om, admitted: adm } =>
InferResult {
typed: semantic_expr_error_node(message: concat("constructor call admission refused for '", fname, "'"), span: span),
diagnostics: [make_error_node(
diagnostic: ConstructorCallAdmissionRefused {
constructor_module_path: om,
constructor_decl_name: fname,
caller_module_path: scope.module_name,
caller_decl_name: if scope.caller_decl_name == "" { "<unknown>" } else { scope.caller_decl_name },
permitted_callers: adm,
span: span
},
module_name: scope.module_name
)]
}
_ =>
match constructor_reference_admission_early_refusal(callee_name: func_name, span: span, scope: scope) {
Present { value: refusal } => refusal
Expand Down
68 changes: 45 additions & 23 deletions src/v1/04_lookup.dag
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,8 @@ import v1.std.core {
ErrorNode,

CardOptional,
error_type
error_type,
DeclRefCoords, fn_admit_callers, decl_ref_coords_label
}

import std.algebra {
Expand Down Expand Up @@ -47,7 +48,7 @@ import v1.compiler.infer_emit_info {

import v1.compiler.infer_sigs {
ResolvedFuncSig, ResolvedFuncEnv, lookup_resolved_sig,
FuncSigLookup, FuncSigResolved, FuncSigUnresolved, FuncSigAmbiguous
FuncSigLookup, FuncSigResolved, FuncSigUnresolved, FuncSigAmbiguous, FuncSigCallerNotAdmitted
}

import v1.compiler.infer_service {
Expand Down Expand Up @@ -81,11 +82,9 @@ fn lookup_func_sig(func_env: ResolvedFuncEnv, type_env: TypeEnv, name: String) -
match lookup_resolved_sig(env: func_env, name: name) {
FuncSigResolved { sig: sig } => FuncSigResolved { sig: sig }
FuncSigAmbiguous { candidates: cands } => FuncSigAmbiguous { candidates: cands }
FuncSigUnresolved =>
match func_sig_from_global_bare(type_env: type_env, name: name) {
Present { value: sig } => FuncSigResolved { sig: sig }
Absent => FuncSigUnresolved
}
FuncSigCallerNotAdmitted { function_name: fname, owner_module_path: om, admitted: adm } =>
FuncSigCallerNotAdmitted { function_name: fname, owner_module_path: om, admitted: adm }
FuncSigUnresolved => func_sig_from_global_bare(type_env: type_env, name: name)
}
}

Expand All @@ -94,6 +93,7 @@ fn func_sig_if_resolved(lookup: FuncSigLookup) -> ResolvedFuncSig? {
FuncSigResolved { sig: sig } => Present { value: sig }
FuncSigUnresolved => Absent
FuncSigAmbiguous { candidates: _ } => Absent
FuncSigCallerNotAdmitted { function_name: _, owner_module_path: _, admitted: _ } => Absent
}
}

Expand Down Expand Up @@ -195,12 +195,12 @@ fn func_decl_binding_for_call(

data census_reserved_method_name_note: String = "Census precedence law (main-parity): the whole-pool census never serves an algebra method-template name (filter/any/contains/…) as a bare fn sig or tail callable. Those names belong to the known-method bridge in the ExprCall arm — a census sig for the UNLOADED v2.std.algebra typed filter(xs, f) as a plain call and the runtime died NoSuchFunction where main rewrote to the builtin method. Loaded providers are unaffected: lookup_resolved_sig runs before the census fallback."

fn func_sig_from_global_bare(type_env: TypeEnv, name: String) -> ResolvedFuncSig? {
fn func_sig_from_global_bare(type_env: TypeEnv, name: String) -> FuncSigLookup {
if algebra_method_template_name(name: name) {
return none
}
FuncSigUnresolved
} else {
match infer_builtin_call_type(name: name) {
Present { value: _ } => none
Present { value: _ } => FuncSigUnresolved
Absent =>
let borrowed = match lookup_binding_by_name_local(env: type_env, name: name) {
Present { value: binding } =>
Expand All @@ -211,7 +211,7 @@ fn func_sig_from_global_bare(type_env: TypeEnv, name: String) -> ResolvedFuncSig
Present { value: bd } =>
let node = bd.node
match (node.params |> count) > 0 || node.inferred != none || node.type_annotation != none {
false => Absent
false => FuncSigUnresolved
true =>
let excluded = borrowed_generic_param_names(params: node.params, source_indices: type_env.source_indices)
let raw_return = match node.inferred {
Expand All @@ -222,7 +222,7 @@ fn func_sig_from_global_bare(type_env: TypeEnv, name: String) -> ResolvedFuncSig
}
}
if bd.owner_module_path == type_env.module_path {
Present { value: ResolvedFuncSig {
FuncSigResolved { sig: ResolvedFuncSig {
name: name,
params: node.params,
inferred: raw_return,
Expand All @@ -231,18 +231,40 @@ fn func_sig_from_global_bare(type_env: TypeEnv, name: String) -> ResolvedFuncSig
variant_provenance: empty_map()
} }
} else {
let qualified_return = qualify_borrowed_type_names(n: raw_return, owner_module_path: bd.owner_module_path, env: type_env, excluded: excluded)
Present { value: ResolvedFuncSig {
name: name,
params: node.params,
inferred: qualified_return,
is_async: false,
output_provenance: [],
variant_provenance: empty_map()
} }
match fn_admit_callers(n: node, source_indices: type_env.source_indices) {
Present { value: permitted } =>
if permitted |> any(p => p.module_path == type_env.module_path) {
let qualified_return = qualify_borrowed_type_names(n: raw_return, owner_module_path: bd.owner_module_path, env: type_env, excluded: excluded)
FuncSigResolved { sig: ResolvedFuncSig {
name: name,
params: node.params,
inferred: qualified_return,
is_async: false,
output_provenance: [],
variant_provenance: empty_map()
} }
} else {
FuncSigCallerNotAdmitted {
function_name: name,
owner_module_path: bd.owner_module_path,
admitted: permitted |> map(p => decl_ref_coords_label(coords: p))
}
}
Absent =>
let qualified_return = qualify_borrowed_type_names(n: raw_return, owner_module_path: bd.owner_module_path, env: type_env, excluded: excluded)
FuncSigResolved { sig: ResolvedFuncSig {
name: name,
params: node.params,
inferred: qualified_return,
is_async: false,
output_provenance: [],
variant_provenance: empty_map()
} }
}
}
}
Absent => Absent
Absent => FuncSigUnresolved
}
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/v1/04_sigs.dag
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,7 @@ type FuncSigLookup
= FuncSigResolved { sig: ResolvedFuncSig }
| FuncSigUnresolved
| FuncSigAmbiguous { candidates: List<String> }
| FuncSigCallerNotAdmitted { function_name: String, owner_module_path: String, admitted: List<String> }

type ChainSigScan {
first_sig: ResolvedFuncSig?
Expand Down
69 changes: 68 additions & 1 deletion src/v1/stage0/src/v1_compiler_infer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ pub use crate::v1_compiler_infer_service::{
};
pub use crate::v1_compiler_infer_service::{OpEntry, ServiceMethodResult, UniqueAccum};
use crate::v1_compiler_infer_sigs::FuncSigLookup::{
FuncSigAmbiguous, FuncSigResolved, FuncSigUnresolved,
FuncSigAmbiguous, FuncSigCallerNotAdmitted, FuncSigResolved, FuncSigUnresolved,
};
pub use crate::v1_compiler_infer_sigs::{flatten_parent_envs, resolve_func_sigs};
pub use crate::v1_compiler_infer_sigs::{
Expand Down Expand Up @@ -4992,6 +4992,40 @@ pub fn infer_expr_body(
span.clone(),
scope.clone(),
),
FuncSigLookup::FuncSigCallerNotAdmitted {
function_name: fname,
owner_module_path: om,
admitted: adm,
..
} => Rc::new(InferResult {
typed: semantic_expr_error_node(
v1_rt::concat(
v1_rt::concat(
"constructor call admission refused for '".to_string(),
fname.clone(),
),
"'".to_string(),
),
span.clone(),
),
diagnostics: Rc::new(vec![make_error_node(
Rc::new(CompilerDiagnostic::ConstructorCallAdmissionRefused {
constructor_module_path: om.clone(),
constructor_decl_name: fname.clone(),
caller_module_path: scope.module_name.clone(),
caller_decl_name: if (scope.caller_decl_name.clone()
== "".to_string())
{
"<unknown>".to_string()
} else {
scope.caller_decl_name.clone()
},
permitted_callers: adm.clone(),
span: span.clone(),
}),
scope.module_name.clone(),
)]),
}),
FuncSigLookup::FuncSigUnresolved => {
match lookup_binding_by_name(scope.type_env.clone(), name.clone()) {
Some(gbinding) => {
Expand Down Expand Up @@ -5344,6 +5378,39 @@ pub fn infer_expr_body(
span.clone(),
scope.clone(),
),
FuncSigLookup::FuncSigCallerNotAdmitted {
function_name: fname,
owner_module_path: om,
admitted: adm,
..
} => Rc::new(InferResult {
typed: semantic_expr_error_node(
v1_rt::concat(
v1_rt::concat(
"constructor call admission refused for '".to_string(),
fname.clone(),
),
"'".to_string(),
),
span.clone(),
),
diagnostics: Rc::new(vec![make_error_node(
Rc::new(CompilerDiagnostic::ConstructorCallAdmissionRefused {
constructor_module_path: om.clone(),
constructor_decl_name: fname.clone(),
caller_module_path: scope.module_name.clone(),
caller_decl_name: if (scope.caller_decl_name.clone() == "".to_string())
{
"<unknown>".to_string()
} else {
scope.caller_decl_name.clone()
},
permitted_callers: adm.clone(),
span: span.clone(),
}),
scope.module_name.clone(),
)]),
}),
_ => {
match constructor_reference_admission_early_refusal(
func_name.clone(),
Expand Down
Loading
Loading