Index: libcxx/docs/Status/Cxx20Issues.csv
===================================================================
--- libcxx/docs/Status/Cxx20Issues.csv
+++ libcxx/docs/Status/Cxx20Issues.csv
@@ -291,7 +291,7 @@
 "`3387 <https://wg21.link/LWG3387>`__","|sect|\ [range.reverse.view] ``reverse_view<V>``\  unintentionally requires ``range<const V>``\ ","Prague","","","|ranges|"
 "`3388 <https://wg21.link/LWG3388>`__","``view``\  iterator types have ill-formed ``<=>``\  operators","Prague","","","|ranges|"
 "`3389 <https://wg21.link/LWG3389>`__","A move-only iterator still does not have a ``counted_iterator``\ ","Prague","","","|ranges|"
-"`3390 <https://wg21.link/LWG3390>`__","``make_move_iterator()``\  cannot be used to construct a ``move_iterator``\  for a move-only iterator","Prague","","","|ranges|"
+"`3390 <https://wg21.link/LWG3390>`__","``make_move_iterator()``\  cannot be used to construct a ``move_iterator``\  for a move-only iterator","Prague","|Complete|","14.0","|ranges|"
 "`3393 <https://wg21.link/LWG3393>`__","Missing/incorrect feature test macro for coroutines","Prague","|Complete|","14.0"
 "`3395 <https://wg21.link/LWG3395>`__","Definition for three-way comparison needs to be updated (US 152)","Prague","","","|spaceship|"
 "`3396 <https://wg21.link/LWG3396>`__","Clarify point of reference for ``source_location::current()``\  (DE 169)","Prague","",""
Index: libcxx/include/__iterator/move_iterator.h
===================================================================
--- libcxx/include/__iterator/move_iterator.h
+++ libcxx/include/__iterator/move_iterator.h
@@ -12,6 +12,7 @@
 
 #include <__config>
 #include <__iterator/iterator_traits.h>
+#include <__utility/move.h>
 #include <type_traits>
 
 #if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
@@ -53,7 +54,7 @@
     move_iterator() : __current_() {}
 
     _LIBCPP_HIDE_FROM_ABI _LIBCPP_CONSTEXPR_AFTER_CXX14
-    explicit move_iterator(_Iter __i) : __current_(__i) {}
+    explicit move_iterator(_Iter __i) : __current_(_VSTD::move(__i)) {}
 
     template <class _Up, class = __enable_if_t<
         !is_same<_Up, _Iter>::value && is_convertible<const _Up&, _Iter>::value
@@ -176,7 +177,7 @@
 move_iterator<_Iter>
 make_move_iterator(_Iter __i)
 {
-    return move_iterator<_Iter>(__i);
+    return move_iterator<_Iter>(_VSTD::move(__i));
 }
 
 _LIBCPP_END_NAMESPACE_STD
Index: libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/iter.pass.cpp
===================================================================
--- libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/iter.pass.cpp
+++ libcxx/test/std/iterators/predef.iterators/move.iterators/move.iter.ops/move.iter.op.const/iter.pass.cpp
@@ -16,33 +16,73 @@
 
 #include <iterator>
 #include <cassert>
+#include <utility>
 
 #include "test_macros.h"
 #include "test_iterators.h"
 
 template <class It>
-void
-test(It i)
+TEST_CONSTEXPR_CXX17 bool test()
 {
-    std::move_iterator<It> r(i);
-    assert(r.base() == i);
+  static_assert( std::is_constructible<std::move_iterator<It>, const It&>::value, "");
+  static_assert( std::is_constructible<std::move_iterator<It>, It&&>::value, "");
+  static_assert(!std::is_convertible<const It&, std::move_iterator<It>>::value, "");
+  static_assert(!std::is_convertible<It&&, std::move_iterator<It>>::value, "");
+
+  char s[] = "123";
+  {
+    It it = It(s);
+    std::move_iterator<It> r(it);
+    assert(base(r.base()) == s);
+  }
+  {
+    It it = It(s);
+    std::move_iterator<It> r(std::move(it));
+    assert(base(r.base()) == s);
+  }
+  return true;
+}
+
+template <class It>
+TEST_CONSTEXPR_CXX17 bool test_moveonly()
+{
+  static_assert(!std::is_constructible<std::move_iterator<It>, const It&>::value, "");
+  static_assert( std::is_constructible<std::move_iterator<It>, It&&>::value, "");
+  static_assert(!std::is_convertible<const It&, std::move_iterator<It>>::value, "");
+  static_assert(!std::is_convertible<It&&, std::move_iterator<It>>::value, "");
+
+  char s[] = "123";
+  {
+    It it = It(s);
+    std::move_iterator<It> r(std::move(it));
+    assert(base(r.base()) == s);
+  }
+  return true;
 }
 
 int main(int, char**)
 {
-    char s[] = "123";
-    test(cpp17_input_iterator<char*>(s));
-    test(forward_iterator<char*>(s));
-    test(bidirectional_iterator<char*>(s));
-    test(random_access_iterator<char*>(s));
-    test(s);
+  test<cpp17_input_iterator<char*> >();
+  test<forward_iterator<char*> >();
+  test<bidirectional_iterator<char*> >();
+  test<random_access_iterator<char*> >();
+  test<char*>();
+  test<const char*>();
 
 #if TEST_STD_VER > 14
-    {
-    constexpr const char *p = "123456789";
-    constexpr std::move_iterator<const char *> it(p);
-    static_assert(it.base() == p);
-    }
+  static_assert(test<cpp17_input_iterator<char*>>());
+  static_assert(test<forward_iterator<char*>>());
+  static_assert(test<bidirectional_iterator<char*>>());
+  static_assert(test<random_access_iterator<char*>>());
+  static_assert(test<char*>());
+  static_assert(test<const char*>());
+#endif
+
+#if TEST_STD_VER > 17
+  test<contiguous_iterator<char*>>();
+  test_moveonly<cpp20_input_iterator<char*>>();
+  static_assert(test<contiguous_iterator<char*>>());
+  static_assert(test_moveonly<cpp20_input_iterator<char*>>());
 #endif
 
   return 0;