diff --git a/cmp/compare.go b/cmp/compare.go
index 177fc10..5527f01 100644
--- a/cmp/compare.go
+++ b/cmp/compare.go
@@ -54,11 +54,10 @@
 // If at least one Ignore exists in S, then the comparison is ignored.
 // If the number of Transformer and Comparer options in S is greater than one,
 // then Equal panics because it is ambiguous which option to use.
-// If S contains a single Transformer, then apply that transformer on the
-// current values and recursively call Equal on the transformed output values.
-// If S contains a single Comparer, then use that Comparer to determine whether
-// the current values are equal or not.
-// Otherwise, S is empty and evaluation proceeds to the next rule.
+// If S contains a single Transformer, then use that to transform the current
+// values and recursively call Equal on the output values.
+// If S contains a single Comparer, then use that to compare the current values.
+// Otherwise, evaluation proceeds to the next rule.
 //
 // • If the values have an Equal method of the form "(T) Equal(T) bool" or
 // "(T) Equal(I) bool" where T is assignable to I, then use the result of
@@ -119,8 +118,7 @@
 
 	// These fields, once set by processOption, will not change.
 	exporters map[reflect.Type]bool // Set of structs with unexported field visibility
-	optsIgn   []option              // List of all ignore options without value filters
-	opts      []option              // List of all other options
+	opts      Options               // List of all fundamental and filter options
 }
 
 func newState(opts []Option) *state {
@@ -128,22 +126,24 @@
 	for _, opt := range opts {
 		s.processOption(opt)
 	}
-	// Move Ignore options to the front so that they are evaluated first.
-	for i, j := 0, 0; i < len(s.opts); i++ {
-		if s.opts[i].op == nil {
-			s.opts[i], s.opts[j] = s.opts[j], s.opts[i]
-			j++
-		}
-	}
 	return s
 }
 
 func (s *state) processOption(opt Option) {
 	switch opt := opt.(type) {
+	case nil:
 	case Options:
 		for _, o := range opt {
 			s.processOption(o)
 		}
+	case coreOption:
+		type filtered interface {
+			isFiltered() bool
+		}
+		if fopt, ok := opt.(filtered); ok && !fopt.isFiltered() {
+			panic(fmt.Sprintf("cannot use an unfiltered option: %v", opt))
+		}
+		s.opts = append(s.opts, opt)
 	case visibleStructs:
 		if s.exporters == nil {
 			s.exporters = make(map[reflect.Type]bool)
@@ -151,15 +151,6 @@
 		for t := range opt {
 			s.exporters[t] = true
 		}
-	case option:
-		if opt.typeFilter == nil && len(opt.pathFilters)+len(opt.valueFilters) == 0 {
-			panic(fmt.Sprintf("cannot use an unfiltered option: %v", opt))
-		}
-		if opt.op == nil && len(opt.valueFilters) == 0 {
-			s.optsIgn = append(s.optsIgn, opt)
-		} else {
-			s.opts = append(s.opts, opt)
-		}
 	case reporter:
 		if s.reporter != nil {
 			panic("difference reporter already registered")
@@ -205,9 +196,10 @@
 		s.curPath.push(&pathStep{typ: t})
 		defer s.curPath.pop()
 	}
+	vx, vy = s.tryExporting(vx, vy)
 
 	// Rule 1: Check whether an option applies on this node in the value tree.
-	if s.tryOptions(&vx, &vy, t) {
+	if s.tryOptions(vx, vy, t) {
 		return
 	}
 
@@ -284,92 +276,39 @@
 	}
 }
 
-// tryOptions iterates through all of the options and evaluates whether any
-// of them can be applied. This may modify the underlying values vx and vy
-// if an unexported field is being forcibly exported.
-func (s *state) tryOptions(vx, vy *reflect.Value, t reflect.Type) bool {
-	// Try all ignore options that do not depend on the value first.
-	// This avoids possible panics when processing unexported fields.
-	for _, opt := range s.optsIgn {
-		var v reflect.Value // Dummy value; should never be used
-		if s.applyFilters(v, v, t, opt) {
-			return true // Ignore option applied
-		}
-	}
-
-	// Since the values must be used after this point, verify that the values
-	// are either exported or can be forcibly exported.
+func (s *state) tryExporting(vx, vy reflect.Value) (reflect.Value, reflect.Value) {
 	if sf, ok := s.curPath[len(s.curPath)-1].(*structField); ok && sf.unexported {
-		if !sf.force {
-			const help = "consider using AllowUnexported or cmpopts.IgnoreUnexported"
-			panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help))
+		if sf.force {
+			// Use unsafe pointer arithmetic to get read-write access to an
+			// unexported field in the struct.
+			vx = unsafeRetrieveField(sf.pvx, sf.field)
+			vy = unsafeRetrieveField(sf.pvy, sf.field)
+		} else {
+			// We are not allowed to export the value, so invalidate them
+			// so that tryOptions can panic later if not explicitly ignored.
+			vx = nothing
+			vy = nothing
 		}
+	}
+	return vx, vy
+}
 
-		// Use unsafe pointer arithmetic to get read-write access to an
-		// unexported field in the struct.
-		*vx = unsafeRetrieveField(sf.pvx, sf.field)
-		*vy = unsafeRetrieveField(sf.pvy, sf.field)
+func (s *state) tryOptions(vx, vy reflect.Value, t reflect.Type) bool {
+	// If there were no FilterValues, we will not detect invalid inputs,
+	// so manually check for them and append invalid if necessary.
+	// We still evaluate the options since an ignore can override invalid.
+	opts := s.opts
+	if !vx.IsValid() || !vy.IsValid() {
+		opts = Options{opts, invalid{}}
 	}
 
-	// Try all other options now.
-	optIdx := -1 // Index of Option to apply
-	for i, opt := range s.opts {
-		if !s.applyFilters(*vx, *vy, t, opt) {
-			continue
-		}
-		if opt.op == nil {
-			return true // Ignored comparison
-		}
-		if optIdx >= 0 {
-			panic(fmt.Sprintf("ambiguous set of options at %#v\n\n%v\n\n%v\n", s.curPath, s.opts[optIdx], opt))
-		}
-		optIdx = i
-	}
-	if optIdx >= 0 {
-		s.applyOption(*vx, *vy, t, s.opts[optIdx])
-		return true
+	// Evaluate all filters and apply the remaining options.
+	if opt := opts.filter(s, vx, vy, t); opt != nil {
+		return opt.apply(s, vx, vy)
 	}
 	return false
 }
 
-func (s *state) applyFilters(vx, vy reflect.Value, t reflect.Type, opt option) bool {
-	if opt.typeFilter != nil {
-		if !t.AssignableTo(opt.typeFilter) {
-			return false
-		}
-	}
-	for _, f := range opt.pathFilters {
-		if !f(s.curPath) {
-			return false
-		}
-	}
-	for _, f := range opt.valueFilters {
-		if !t.AssignableTo(f.in) || !s.callTTBFunc(f.fnc, vx, vy) {
-			return false
-		}
-	}
-	return true
-}
-
-func (s *state) applyOption(vx, vy reflect.Value, t reflect.Type, opt option) {
-	switch op := opt.op.(type) {
-	case *transformer:
-		// Update path before calling the Transformer so that dynamic checks
-		// will use the updated path.
-		s.curPath.push(&transform{pathStep{op.fnc.Type().Out(0)}, op})
-		defer s.curPath.pop()
-
-		vx = s.callTRFunc(op.fnc, vx)
-		vy = s.callTRFunc(op.fnc, vy)
-		s.compareAny(vx, vy)
-		return
-	case *comparer:
-		eq := s.callTTBFunc(op.fnc, vx, vy)
-		s.report(eq, vx, vy)
-		return
-	}
-}
-
 func (s *state) tryMethod(vx, vy reflect.Value, t reflect.Type) bool {
 	// Check if this type even has an Equal method.
 	m, ok := t.MethodByName("Equal")
diff --git a/cmp/compare_test.go b/cmp/compare_test.go
index a0c003e..36a4ecf 100644
--- a/cmp/compare_test.go
+++ b/cmp/compare_test.go
@@ -113,7 +113,7 @@
 			cmp.Comparer(func(x, y int) bool { return true }),
 			cmp.Transformer("", func(x int) float64 { return float64(x) }),
 		},
-		wantPanic: "ambiguous set of options",
+		wantPanic: "ambiguous set of applicable options",
 	}, {
 		label: label,
 		x:     1,
@@ -380,7 +380,7 @@
 			cmp.Transformer("", func(in int) int { return in / 2 }),
 			cmp.Transformer("", func(in int) int { return in }),
 		},
-		wantPanic: "ambiguous set of options",
+		wantPanic: "ambiguous set of applicable options",
 	}, {
 		label: label,
 		x:     []int{0, -5, 0, -1},
diff --git a/cmp/options.go b/cmp/options.go
index 0498a55..a4e159a 100644
--- a/cmp/options.go
+++ b/cmp/options.go
@@ -23,11 +23,38 @@
 // The cmp/cmpopts package provides helper functions for creating options that
 // may be used with Equal and Diff.
 type Option interface {
-	// Prevent Option from being equivalent to interface{}, which provides
-	// a small type checking benefit by preventing Equal(opt, x, y).
-	option()
+	// filter applies all filters and returns the option that remains.
+	// Each option may only read s.curPath and call s.callTTBFunc.
+	//
+	// An Options is returned only if multiple comparers or transformers
+	// can apply simultaneously and will only contain values of those types
+	// or sub-Options containing values of those types.
+	filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption
 }
 
+// applicableOption represents the following types:
+//	Fundamental: ignore | invalid | *comparer | *transformer
+//	Grouping:    Options
+type applicableOption interface {
+	Option
+
+	// apply executes the option and reports whether the option was applied.
+	// Each option may mutate s.
+	apply(s *state, vx, vy reflect.Value) bool
+}
+
+// coreOption represents the following types:
+//	Fundamental: ignore | invalid | *comparer | *transformer
+//	Filters:     *pathFilter | *valuesFilter
+type coreOption interface {
+	Option
+	isCore()
+}
+
+type core struct{}
+
+func (core) isCore() {}
+
 // Options is a list of Option values that also satisfies the Option interface.
 // Helper comparison packages may return an Options value when packing multiple
 // Option values into a single Option. When this package processes an Options,
@@ -37,79 +64,44 @@
 // on all individual options held within.
 type Options []Option
 
-func (Options) option() {}
-
-type (
-	pathFilter  func(Path) bool
-	valueFilter struct {
-		in  reflect.Type  // T
-		fnc reflect.Value // func(T, T) bool
-	}
-)
-
-type option struct {
-	typeFilter   reflect.Type
-	pathFilters  []pathFilter
-	valueFilters []valueFilter
-
-	// op is the operation to perform. If nil, then this acts as an ignore.
-	op interface{} // nil | *transformer | *comparer
-}
-
-func (option) option() {}
-
-func (o option) String() string {
-	// TODO: Add information about the caller?
-	// TODO: Maintain the order that filters were added?
-
-	var ss []string
-	switch op := o.op.(type) {
-	case *transformer:
-		fn := getFuncName(op.fnc.Pointer())
-		ss = append(ss, fmt.Sprintf("Transformer(%s, %s)", op.name, fn))
-	case *comparer:
-		fn := getFuncName(op.fnc.Pointer())
-		ss = append(ss, fmt.Sprintf("Comparer(%s)", fn))
-	default:
-		ss = append(ss, "Ignore()")
-	}
-
-	for _, f := range o.pathFilters {
-		fn := getFuncName(reflect.ValueOf(f).Pointer())
-		ss = append(ss, fmt.Sprintf("FilterPath(%s)", fn))
-	}
-	for _, f := range o.valueFilters {
-		fn := getFuncName(f.fnc.Pointer())
-		ss = append(ss, fmt.Sprintf("FilterValues(%s)", fn))
-	}
-	return strings.Join(ss, "\n\t")
-}
-
-// getFuncName returns a short function name from the pointer.
-// The string parsing logic works up until Go1.9.
-func getFuncName(p uintptr) string {
-	fnc := runtime.FuncForPC(p)
-	if fnc == nil {
-		return "<unknown>"
-	}
-	name := fnc.Name() // E.g., "long/path/name/mypkg.(mytype).(long/path/name/mypkg.myfunc)-fm"
-	if strings.HasSuffix(name, ")-fm") || strings.HasSuffix(name, ")·fm") {
-		// Strip the package name from method name.
-		name = strings.TrimSuffix(name, ")-fm")
-		name = strings.TrimSuffix(name, ")·fm")
-		if i := strings.LastIndexByte(name, '('); i >= 0 {
-			methodName := name[i+1:] // E.g., "long/path/name/mypkg.myfunc"
-			if j := strings.LastIndexByte(methodName, '.'); j >= 0 {
-				methodName = methodName[j+1:] // E.g., "myfunc"
+func (opts Options) filter(s *state, vx, vy reflect.Value, t reflect.Type) (out applicableOption) {
+	for _, opt := range opts {
+		switch opt := opt.filter(s, vx, vy, t); opt.(type) {
+		case ignore:
+			return ignore{} // Only ignore can short-circuit evaluation
+		case invalid:
+			out = invalid{} // Takes precedence over comparer or transformer
+		case *comparer, *transformer, Options:
+			switch out.(type) {
+			case nil:
+				out = opt
+			case invalid:
+				// Keep invalid
+			case *comparer, *transformer, Options:
+				out = Options{out, opt} // Conflicting comparers or transformers
 			}
-			name = name[:i] + methodName // E.g., "long/path/name/mypkg.(mytype)." + "myfunc"
 		}
 	}
-	if i := strings.LastIndexByte(name, '/'); i >= 0 {
-		// Strip the package name.
-		name = name[i+1:] // E.g., "mypkg.(mytype).myfunc"
+	return out
+}
+
+func (opts Options) apply(s *state, _, _ reflect.Value) bool {
+	const warning = "ambiguous set of applicable options"
+	const help = "consider using filters to ensure at most one Comparer or Transformer may apply"
+	var ss []string
+	for _, opt := range flattenOptions(nil, opts) {
+		ss = append(ss, fmt.Sprint(opt))
 	}
-	return name
+	set := strings.Join(ss, "\n\t")
+	panic(fmt.Sprintf("%s at %#v:\n\t%s\n%s", warning, s.curPath, set, help))
+}
+
+func (opts Options) String() string {
+	var ss []string
+	for _, opt := range opts {
+		ss = append(ss, fmt.Sprint(opt))
+	}
+	return fmt.Sprintf("Options{%s}", strings.Join(ss, ", "))
 }
 
 // FilterPath returns a new Option where opt is only evaluated if filter f
@@ -121,20 +113,28 @@
 	if f == nil {
 		panic("invalid path filter function")
 	}
-	switch opt := opt.(type) {
-	case Options:
-		var opts []Option
-		for _, o := range opt {
-			opts = append(opts, FilterPath(f, o)) // Append to slice copy
-		}
-		return Options(opts)
-	case option:
-		n := len(opt.pathFilters)
-		opt.pathFilters = append(opt.pathFilters[:n:n], f) // Append to copy
-		return opt
-	default:
-		panic(fmt.Sprintf("unknown option type: %T", opt))
+	if opt := normalizeOption(opt); opt != nil {
+		return &pathFilter{fnc: f, opt: opt}
 	}
+	return nil
+}
+
+type pathFilter struct {
+	core
+	fnc func(Path) bool
+	opt Option
+}
+
+func (f pathFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption {
+	if f.fnc(s.curPath) {
+		return f.opt.filter(s, vx, vy, t)
+	}
+	return nil
+}
+
+func (f pathFilter) String() string {
+	fn := getFuncName(reflect.ValueOf(f.fnc).Pointer())
+	return fmt.Sprintf("FilterPath(%s, %v)", fn, f.opt)
 }
 
 // FilterValues returns a new Option where opt is only evaluated if filter f,
@@ -155,28 +155,58 @@
 	if !function.IsType(v.Type(), function.ValueFilter) || v.IsNil() {
 		panic(fmt.Sprintf("invalid values filter function: %T", f))
 	}
-	switch opt := opt.(type) {
-	case Options:
-		var opts []Option
-		for _, o := range opt {
-			opts = append(opts, FilterValues(f, o)) // Append to slice copy
+	if opt := normalizeOption(opt); opt != nil {
+		vf := &valuesFilter{fnc: v, opt: opt}
+		if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
+			vf.typ = ti
 		}
-		return Options(opts)
-	case option:
-		n := len(opt.valueFilters)
-		vf := valueFilter{v.Type().In(0), v}
-		opt.valueFilters = append(opt.valueFilters[:n:n], vf) // Append to copy
-		return opt
-	default:
-		panic(fmt.Sprintf("unknown option type: %T", opt))
+		return vf
 	}
+	return nil
+}
+
+type valuesFilter struct {
+	core
+	typ reflect.Type  // T
+	fnc reflect.Value // func(T, T) bool
+	opt Option
+}
+
+func (f valuesFilter) filter(s *state, vx, vy reflect.Value, t reflect.Type) applicableOption {
+	if !vx.IsValid() || !vy.IsValid() {
+		return invalid{}
+	}
+	if (f.typ == nil || t.AssignableTo(f.typ)) && s.callTTBFunc(f.fnc, vx, vy) {
+		return f.opt.filter(s, vx, vy, t)
+	}
+	return nil
+}
+
+func (f valuesFilter) String() string {
+	fn := getFuncName(f.fnc.Pointer())
+	return fmt.Sprintf("FilterValues(%s, %v)", fn, f.opt)
 }
 
 // Ignore is an Option that causes all comparisons to be ignored.
 // This value is intended to be combined with FilterPath or FilterValues.
 // It is an error to pass an unfiltered Ignore option to Equal.
-func Ignore() Option {
-	return option{}
+func Ignore() Option { return ignore{} }
+
+type ignore struct{ core }
+
+func (ignore) isFiltered() bool                                                     { return false }
+func (ignore) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return ignore{} }
+func (ignore) apply(_ *state, _, _ reflect.Value) bool                              { return true }
+func (ignore) String() string                                                       { return "Ignore()" }
+
+// invalid is a sentinel Option type to indicate that some options could not
+// be evaluated due to unexported fields.
+type invalid struct{ core }
+
+func (invalid) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption { return invalid{} }
+func (invalid) apply(s *state, _, _ reflect.Value) bool {
+	const help = "consider using AllowUnexported or cmpopts.IgnoreUnexported"
+	panic(fmt.Sprintf("cannot handle unexported field: %#v\n%s", s.curPath, help))
 }
 
 // Transformer returns an Option that applies a transformation function that
@@ -202,18 +232,45 @@
 	if !isValid(name) {
 		panic(fmt.Sprintf("invalid name: %q", name))
 	}
-	opt := option{op: &transformer{name, reflect.ValueOf(f)}}
+	tr := &transformer{name: name, fnc: reflect.ValueOf(f)}
 	if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
-		opt.typeFilter = ti
+		tr.typ = ti
 	}
-	return opt
+	return tr
 }
 
 type transformer struct {
+	core
 	name string
+	typ  reflect.Type  // T
 	fnc  reflect.Value // func(T) R
 }
 
+func (tr *transformer) isFiltered() bool { return tr.typ != nil }
+
+func (tr *transformer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applicableOption {
+	if tr.typ == nil || t.AssignableTo(tr.typ) {
+		return tr
+	}
+	return nil
+}
+
+func (tr *transformer) apply(s *state, vx, vy reflect.Value) bool {
+	// Update path before calling the Transformer so that dynamic checks
+	// will use the updated path.
+	s.curPath.push(&transform{pathStep{tr.fnc.Type().Out(0)}, tr})
+	defer s.curPath.pop()
+
+	vx = s.callTRFunc(tr.fnc, vx)
+	vy = s.callTRFunc(tr.fnc, vy)
+	s.compareAny(vx, vy)
+	return true
+}
+
+func (tr transformer) String() string {
+	return fmt.Sprintf("Transformer(%s, %s)", tr.name, getFuncName(tr.fnc.Pointer()))
+}
+
 // Comparer returns an Option that determines whether two values are equal
 // to each other.
 //
@@ -231,17 +288,38 @@
 	if !function.IsType(v.Type(), function.Equal) || v.IsNil() {
 		panic(fmt.Sprintf("invalid comparer function: %T", f))
 	}
-	opt := option{op: &comparer{v}}
+	cm := &comparer{fnc: v}
 	if ti := v.Type().In(0); ti.Kind() != reflect.Interface || ti.NumMethod() > 0 {
-		opt.typeFilter = ti
+		cm.typ = ti
 	}
-	return opt
+	return cm
 }
 
 type comparer struct {
+	core
+	typ reflect.Type  // T
 	fnc reflect.Value // func(T, T) bool
 }
 
+func (cm *comparer) isFiltered() bool { return cm.typ != nil }
+
+func (cm *comparer) filter(_ *state, _, _ reflect.Value, t reflect.Type) applicableOption {
+	if cm.typ == nil || t.AssignableTo(cm.typ) {
+		return cm
+	}
+	return nil
+}
+
+func (cm *comparer) apply(s *state, vx, vy reflect.Value) bool {
+	eq := s.callTTBFunc(cm.fnc, vx, vy)
+	s.report(eq, vx, vy)
+	return true
+}
+
+func (cm comparer) String() string {
+	return fmt.Sprintf("Comparer(%s)", getFuncName(cm.fnc.Pointer()))
+}
+
 // AllowUnexported returns an Option that forcibly allows operations on
 // unexported fields in certain structs, which are specified by passing in a
 // value of each struct type.
@@ -285,7 +363,9 @@
 
 type visibleStructs map[reflect.Type]bool
 
-func (visibleStructs) option() {}
+func (visibleStructs) filter(_ *state, _, _ reflect.Value, _ reflect.Type) applicableOption {
+	panic("not implemented")
+}
 
 // reporter is an Option that configures how differences are reported.
 type reporter interface {
@@ -305,3 +385,62 @@
 	// which is possible with maps and slices.
 	Report(x, y reflect.Value, eq bool, p Path)
 }
+
+// normalizeOption normalizes the input options such that all Options groups
+// are flattened and groups with a single element are reduced to that element.
+// Only coreOptions and Options containing coreOptions are allowed.
+func normalizeOption(src Option) Option {
+	switch opts := flattenOptions(nil, Options{src}); len(opts) {
+	case 0:
+		return nil
+	case 1:
+		return opts[0]
+	default:
+		return opts
+	}
+}
+
+// flattenOptions copies all options in src to dst as a flat list.
+// Only coreOptions and Options containing coreOptions are allowed.
+func flattenOptions(dst, src Options) Options {
+	for _, opt := range src {
+		switch opt := opt.(type) {
+		case nil:
+			continue
+		case Options:
+			dst = flattenOptions(dst, opt)
+		case coreOption:
+			dst = append(dst, opt)
+		default:
+			panic(fmt.Sprintf("invalid option type: %T", opt))
+		}
+	}
+	return dst
+}
+
+// getFuncName returns a short function name from the pointer.
+// The string parsing logic works up until Go1.9.
+func getFuncName(p uintptr) string {
+	fnc := runtime.FuncForPC(p)
+	if fnc == nil {
+		return "<unknown>"
+	}
+	name := fnc.Name() // E.g., "long/path/name/mypkg.(mytype).(long/path/name/mypkg.myfunc)-fm"
+	if strings.HasSuffix(name, ")-fm") || strings.HasSuffix(name, ")·fm") {
+		// Strip the package name from method name.
+		name = strings.TrimSuffix(name, ")-fm")
+		name = strings.TrimSuffix(name, ")·fm")
+		if i := strings.LastIndexByte(name, '('); i >= 0 {
+			methodName := name[i+1:] // E.g., "long/path/name/mypkg.myfunc"
+			if j := strings.LastIndexByte(methodName, '.'); j >= 0 {
+				methodName = methodName[j+1:] // E.g., "myfunc"
+			}
+			name = name[:i] + methodName // E.g., "long/path/name/mypkg.(mytype)." + "myfunc"
+		}
+	}
+	if i := strings.LastIndexByte(name, '/'); i >= 0 {
+		// Strip the package name.
+		name = name[i+1:] // E.g., "mypkg.(mytype).myfunc"
+	}
+	return name
+}
diff --git a/cmp/options_test.go b/cmp/options_test.go
index 2bde798..009b524 100644
--- a/cmp/options_test.go
+++ b/cmp/options_test.go
@@ -130,7 +130,7 @@
 		label:     "FilterPath",
 		fnc:       FilterPath,
 		args:      []interface{}{func(Path) bool { return true }, &defaultReporter{}},
-		wantPanic: "unknown option type",
+		wantPanic: "invalid option type",
 	}, {
 		label: "FilterPath",
 		fnc:   FilterPath,
@@ -139,7 +139,7 @@
 		label:     "FilterPath",
 		fnc:       FilterPath,
 		args:      []interface{}{func(Path) bool { return true }, Options{Ignore(), &defaultReporter{}}},
-		wantPanic: "unknown option type",
+		wantPanic: "invalid option type",
 	}, {
 		label:     "FilterValues",
 		fnc:       FilterValues,
@@ -172,7 +172,7 @@
 		label:     "FilterValues",
 		fnc:       FilterValues,
 		args:      []interface{}{func(int, int) bool { return true }, &defaultReporter{}},
-		wantPanic: "unknown option type",
+		wantPanic: "invalid option type",
 	}, {
 		label: "FilterValues",
 		fnc:   FilterValues,
@@ -181,7 +181,7 @@
 		label:     "FilterValues",
 		fnc:       FilterValues,
 		args:      []interface{}{func(int, int) bool { return true }, Options{Ignore(), &defaultReporter{}}},
-		wantPanic: "unknown option type",
+		wantPanic: "invalid option type",
 	}}
 
 	for _, tt := range tests {
