# Buggy code
def _detect_c_or_cpp_compiler(self, lang, evar, want_cross):
    popen_exceptions = {}
    compilers, ccache, is_cross, exe_wrap = self._get_compilers(lang, evar, want_cross)
    for compiler in compilers:
        if isinstance(compiler, str):
            compiler = [compiler]
        if "cl" in compiler or "cl.exe" in compiler:
            arg = "/?"
        else:
            arg = "--version"
        try:
            p, out, err = Popen_safe(compiler + [arg])
        except OSError as e:
            popen_exceptions[" ".join(compiler + [arg])] = e
            continue
        version = search_version(out)
        if "Free Software Foundation" in out:
            defines = self.get_gnu_compiler_defines(compiler)
            if not defines:
                popen_exceptions[compiler] = "no pre-processor defines"
                continue
            gtype = self.get_gnu_compiler_type(defines)
            version = self.get_gnu_version_from_defines(defines)
            cls = GnuCCompiler if lang == "c" else GnuCPPCompiler
            return cls(ccache + compiler, version, gtype, is_cross, exe_wrap, defines)
        if "clang" in out:
            if "Apple" in out or for_darwin(want_cross, self):
                cltype = CLANG_OSX
            elif "windows" in out or for_windows(want_cross, self):
                cltype = CLANG_WIN
            else:
                cltype = CLANG_STANDARD
            cls = ClangCCompiler if lang == "c" else ClangCPPCompiler
            return cls(ccache + compiler, version, cltype, is_cross, exe_wrap)
        if "Microsoft" in out or "Microsoft" in err:
            # Visual Studio prints version number to stderr but
            # everything else to stdout. Why? Lord only knows.
            version = search_version(err)
            cls = VisualStudioCCompiler if lang == "c" else VisualStudioCPPCompiler
            return cls(compiler, version, is_cross, exe_wrap)
        if "(ICC)" in out:
            # TODO: add microsoft add check OSX
            inteltype = ICC_STANDARD
            cls = IntelCCompiler if lang == "c" else IntelCPPCompiler
            return cls(ccache + compiler, version, inteltype, is_cross, exe_wrap)
    self._handle_exceptions(popen_exceptions, compilers)


# Traceback (TypeError)
$ CC=cgcc meson ../ --prefix=/home/hughsie/.root
The Meson build system
Version: 0.42.0.dev1
Source dir: /home/hughsie/Code/fwupd
Build dir: /home/hughsie/Code/fwupd/build
Build type: native build
Project name: fwupd
Traceback (most recent call last):
File "/usr/lib/python3.6/site-packages/mesonbuild/mesonmain.py", line 307, in run
app.generate()
File "/usr/lib/python3.6/site-packages/mesonbuild/mesonmain.py", line 172, in generate
intr = interpreter.Interpreter(b, g)
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreter.py", line 1240, in __init__
self.parse_project()
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreterbase.py", line 111, in parse_project
self.evaluate_codeblock(self.ast, end=1)
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreterbase.py", line 146, in evaluate_codeblock
raise e
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreterbase.py", line 140, in evaluate_codeblock
self.evaluate_statement(cur)
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreterbase.py", line 151, in evaluate_statement
return self.function_call(cur)
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreterbase.py", line 361, in function_call
return self.funcs[func_name](node, self.flatten(posargs), kwargs)
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreterbase.py", line 55, in wrapped
return f(self, node, args, kwargs)
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreter.py", line 1673, in func_project
self.add_languages(proj_langs, True)
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreter.py", line 1789, in add_languages
(comp, cross_comp) = self.detect_compilers(lang, need_cross_compiler)
File "/usr/lib/python3.6/site-packages/mesonbuild/interpreter.py", line 1712, in detect_compilers
comp = self.environment.detect_c_compiler(False)
File "/usr/lib/python3.6/site-packages/mesonbuild/environment.py", line 504, in detect_c_compiler
return self._detect_c_or_cpp_compiler('c', 'CC', want_cross)
File "/usr/lib/python3.6/site-packages/mesonbuild/environment.py", line 475, in _detect_c_or_cpp_compiler
popen_exceptions[compiler] = 'no pre-processor defines'
TypeError: unhashable type: 'list'

# Fixed code
def _detect_c_or_cpp_compiler(self, lang, evar, want_cross):
    popen_exceptions = {}
    compilers, ccache, is_cross, exe_wrap = self._get_compilers(lang, evar, want_cross)
    for compiler in compilers:
        if isinstance(compiler, str):
            compiler = [compiler]
        if "cl" in compiler or "cl.exe" in compiler:
            arg = "/?"
        else:
            arg = "--version"
        try:
            p, out, err = Popen_safe(compiler + [arg])
        except OSError as e:
            popen_exceptions[" ".join(compiler + [arg])] = e
            continue
        version = search_version(out)
        if "Free Software Foundation" in out:
            defines = self.get_gnu_compiler_defines(compiler)
            if not defines:
                popen_exceptions[" ".join(compiler)] = "no pre-processor defines"
                continue
            gtype = self.get_gnu_compiler_type(defines)
            version = self.get_gnu_version_from_defines(defines)
            cls = GnuCCompiler if lang == "c" else GnuCPPCompiler
            return cls(ccache + compiler, version, gtype, is_cross, exe_wrap, defines)
        if "clang" in out:
            if "Apple" in out or for_darwin(want_cross, self):
                cltype = CLANG_OSX
            elif "windows" in out or for_windows(want_cross, self):
                cltype = CLANG_WIN
            else:
                cltype = CLANG_STANDARD
            cls = ClangCCompiler if lang == "c" else ClangCPPCompiler
            return cls(ccache + compiler, version, cltype, is_cross, exe_wrap)
        if "Microsoft" in out or "Microsoft" in err:
            # Visual Studio prints version number to stderr but
            # everything else to stdout. Why? Lord only knows.
            version = search_version(err)
            cls = VisualStudioCCompiler if lang == "c" else VisualStudioCPPCompiler
            return cls(compiler, version, is_cross, exe_wrap)
        if "(ICC)" in out:
            # TODO: add microsoft add check OSX
            inteltype = ICC_STANDARD
            cls = IntelCCompiler if lang == "c" else IntelCPPCompiler
            return cls(ccache + compiler, version, inteltype, is_cross, exe_wrap)
    self._handle_exceptions(popen_exceptions, compilers)