Skip to content

Special Types in a Member Cannot Be Used in Type Parameters #329

@JasonBock

Description

@JasonBock

To Reproduce

Test this code:

var code =
	"""
	using Rocks;
	using System;

	[assembly: Rock(typeof(MockTests.ITypedReference), BuildType.Create | BuildType.Make)]

	namespace MockTests
	{
		public interface ITypedReference
		{
			void Use(TypedReference value);
		}
	}
	""";

Expected behavior
The mock code is generated and compiles.

Actual behavior
Errors occur like this:

error CS0306: The type 'TypedReference' may not be used as a type argument

There are types that can't be passed into type parameters, like pointers and interfaces with static abstract members. I've been able to get around some of this by generating delegates and custom Argument based types. However, TypedReference seems like a one-off "special" case. It's unclear according to the docs which types can't be used in type parameters. This test seems to suggest that the following types will trip CS0306:

  • Pointers
  • ArgIterator
  • RuntimeArgumentHandle
  • TypedReference

Rocks already handles pointers through code generation, so it seems like there's only three types we need handle. There are a couple of strategies to do this:

  • I could define special types to handle these three exceptions, like ArgIteratorArgument, and create custom delegates for the callbacks and return values. However, that's work for three types, which seems like a fair amount of effort for an exceptional case.
  • I look for members that use these types, either for a parameter or the return type:
    • If the member is virtual, meaning, it's not abstract, Rocks simply ignores it as a member that can have expectations set on it, and it doesn't override it.
    • If the member must be implemented in the mock type, I track that in a flag, and report that as a diagnostic.

If I do something here, I may want to create something that generate these projected support types for any given type. That may justify adding the three types into Rocks.

This was found on System.Reflection.Emit.FieldBuilder (the specific method definition is here)

Metadata

Metadata

Assignees

No one assigned

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions