Find a most general common subtype between type1 and type2.

Find the most general type that is a subtype of type2 and, if possible, a subtype of type1. Basically, this return the most specific type between type1 and type2. If nullable types are involved, the information is correctly preserved. If type1 and type2 are incomparable then type2 is preferred (since intersection types are not representable in Nit).

The null value is returned if both type1 and type2 are null.

Examples (with diamond A,B,C,D):

  • intersect_types(A,B) -> B, because B is a subtype of A
  • intersect_types(B,A) -> B, because B is a subtype of A
  • intersect_types(B,C) -> C, B and C are incomparable, type2 is then preferred (B cannot be represented)
  • intersect_types(nullable B,A) -> B, because B<:A and the non-null information is preserved
  • intersect_types(B,nullable C) -> C, type2 is preferred and the non-null information is preserved

Property definitions

nitc $ TypeVisitor :: intersect_types
	# Find a most general common subtype between `type1` and `type2`.
	#
	# Find the most general type that is a subtype of `type2` and, if possible, a subtype of `type1`.
	# Basically, this return the most specific type between `type1` and `type2`.
	# If nullable types are involved, the information is correctly preserved.
	# If `type1` and `type2` are incomparable then `type2` is preferred (since intersection types
	# are not representable in Nit).
	#
	# The `null` value is returned if both `type1` and `type2` are null.
	#
	# Examples (with diamond A,B,C,D):
	#
	# * intersect_types(A,B) -> B, because B is a subtype of A
	# * intersect_types(B,A) -> B, because B is a subtype of A
	# * intersect_types(B,C) -> C, B and C are incomparable,
	#   `type2` is then preferred (`B and C` cannot be represented)
	# * intersect_types(nullable B,A) -> B, because B<:A and the non-null information is preserved
	# * intersect_types(B,nullable C) -> C, `type2` is preferred and the non-null information is preserved
	fun intersect_types(node: ANode, type1, type2: nullable MType): nullable MType
	do
		if type1 == null then return type2
		if type2 == null then return type1

		if not can_be_null(type2) or not can_be_null(type1) then
			type1 = type1.as_notnull
			type2 = type2.as_notnull
		end

		var res
		if is_subtype(type1, type2) then
			res = type1
		else
			res = type2
		end
		return res
	end
src/semantize/typing.nit:687,2--722,4