creating a garbage BASELINK; constructors can't be inherited.  */
     ctors = get_class_binding (totype, complete_ctor_identifier);
 
+  tree to_nonref = non_reference (totype);
   if (MAYBE_CLASS_TYPE_P (fromtype))
     {
-      tree to_nonref = non_reference (totype);
       if (same_type_ignoring_top_level_qualifiers_p (to_nonref, fromtype) ||
          (CLASS_TYPE_P (to_nonref) && CLASS_TYPE_P (fromtype)
           && DERIVED_FROM_P (to_nonref, fromtype)))
       tree conversion_path = TREE_PURPOSE (conv_fns);
       struct z_candidate *old_candidates;
 
+      /* If LOOKUP_NO_CONVERSION, don't consider a conversion function that
+        would need an addional user-defined conversion, i.e. if the return
+        type differs in class-ness from the desired type.  So we avoid
+        considering operator bool when calling a copy constructor.
+
+        This optimization avoids the failure in PR97600, and is allowed by
+        [temp.inst]/9: "If the function selected by overload resolution can be
+        determined without instantiating a class template definition, it is
+        unspecified whether that instantiation actually takes place."  */
+      tree convtype = non_reference (TREE_TYPE (conv_fns));
+      if ((flags & LOOKUP_NO_CONVERSION)
+         && !WILDCARD_TYPE_P (convtype)
+         && (CLASS_TYPE_P (to_nonref)
+             != CLASS_TYPE_P (convtype)))
+       continue;
+
       /* If we are called to convert to a reference type, we are trying to
         find a direct binding, so don't even consider temporaries.  If
         we don't find a direct binding, the caller will try again to
 
--- /dev/null
+// { dg-do compile { target c++20 } }
+
+// Here, normal overload resolution would consider B::operator bool when
+// evaluating A(b), leading to a hard error instantiating Error<int>, but we
+// avoid considering it by noticing that converting bool (a scalar) to A (a
+// class) would require a user-defined conversion, which is not allowed when
+// we're already dealing with the user-defined conversion to A.
+
+// This seems to be allowed by [temp.inst]/9: "If the function selected by
+// overload resolution (12.4) can be determined without instantiating a class
+// template definition, it is unspecified whether that instantiation actually
+// takes place."
+
+template <class T>
+struct Error { static constexpr auto value = T::value; };
+
+struct A { A(const A&); };
+
+template <class T>
+struct B { operator bool() requires Error<T>::value; };
+
+template <class T>
+concept C = requires (B<T> b) { A(b); };
+
+static_assert(!C<int>);
 
--- /dev/null
+// { dg-do compile { target c++20 } }
+
+// But make sure we do consider template conversions that could produce the
+// right type.
+
+template <class T>
+struct Error { static constexpr auto value = T::value; }; // { dg-error "not a member" }
+
+struct A { A(const A&); };
+
+template <class T>
+struct B { template <class U> operator U() requires Error<T>::value; };
+
+template <class T>
+concept C = requires (B<T> b) { A(b); }; // { dg-message "required from here" }
+
+static_assert(!C<int>);