diff --git a/compiler/rustc_feature/src/builtin_attrs.rs b/compiler/rustc_feature/src/builtin_attrs.rs
index 72ea55d5999a2..bb0e989bd812a 100644
--- a/compiler/rustc_feature/src/builtin_attrs.rs
+++ b/compiler/rustc_feature/src/builtin_attrs.rs
@@ -578,12 +578,6 @@ pub const BUILTIN_ATTRIBUTES: &[BuiltinAttribute] = &[
         EncodeCrossCrate::No, coroutines, experimental!(coroutines)
     ),
 
-    // `#[pointee]` attribute to designate the pointee type in SmartPointer derive-macro
-    gated!(
-        pointee, Normal, template!(Word), ErrorFollowing,
-        EncodeCrossCrate::No, derive_smart_pointer, experimental!(pointee)
-    ),
-
     // RFC 3543
     // `#[patchable_function_entry(prefix_nops = m, entry_nops = n)]`
     gated!(
diff --git a/library/core/src/marker.rs b/library/core/src/marker.rs
index 6a83ec2eb1e0e..374fa086aecb7 100644
--- a/library/core/src/marker.rs
+++ b/library/core/src/marker.rs
@@ -1060,7 +1060,7 @@ pub trait FnPtr: Copy + Clone {
 }
 
 /// Derive macro generating impls of traits related to smart pointers.
-#[rustc_builtin_macro]
+#[rustc_builtin_macro(SmartPointer, attributes(pointee))]
 #[allow_internal_unstable(dispatch_from_dyn, coerce_unsized, unsize)]
 #[unstable(feature = "derive_smart_pointer", issue = "123430")]
 pub macro SmartPointer($item:item) {
diff --git a/tests/ui/deriving/auxiliary/another-proc-macro.rs b/tests/ui/deriving/auxiliary/another-proc-macro.rs
new file mode 100644
index 0000000000000..a05175c9de926
--- /dev/null
+++ b/tests/ui/deriving/auxiliary/another-proc-macro.rs
@@ -0,0 +1,45 @@
+//@ force-host
+//@ no-prefer-dynamic
+
+#![crate_type = "proc-macro"]
+#![feature(proc_macro_quote)]
+
+extern crate proc_macro;
+
+use proc_macro::{quote, TokenStream};
+
+#[proc_macro_derive(AnotherMacro, attributes(pointee))]
+pub fn derive(_input: TokenStream) -> TokenStream {
+    quote! {
+        const _: () = {
+            const ANOTHER_MACRO_DERIVED: () = ();
+        };
+    }
+    .into()
+}
+
+#[proc_macro_attribute]
+pub fn pointee(
+    _attr: proc_macro::TokenStream,
+    _item: proc_macro::TokenStream,
+) -> proc_macro::TokenStream {
+    quote! {
+        const _: () = {
+            const POINTEE_MACRO_ATTR_DERIVED: () = ();
+        };
+    }
+    .into()
+}
+
+#[proc_macro_attribute]
+pub fn default(
+    _attr: proc_macro::TokenStream,
+    _item: proc_macro::TokenStream,
+) -> proc_macro::TokenStream {
+    quote! {
+        const _: () = {
+            const DEFAULT_MACRO_ATTR_DERIVED: () = ();
+        };
+    }
+    .into()
+}
diff --git a/tests/ui/deriving/built-in-proc-macro-scope.rs b/tests/ui/deriving/built-in-proc-macro-scope.rs
new file mode 100644
index 0000000000000..41c95f63b135e
--- /dev/null
+++ b/tests/ui/deriving/built-in-proc-macro-scope.rs
@@ -0,0 +1,25 @@
+//@ check-pass
+//@ aux-build: another-proc-macro.rs
+//@ compile-flags: -Zunpretty=expanded
+
+#![feature(derive_smart_pointer)]
+
+#[macro_use]
+extern crate another_proc_macro;
+
+use another_proc_macro::{pointee, AnotherMacro};
+
+#[derive(core::marker::SmartPointer)]
+#[repr(transparent)]
+pub struct Ptr<'a, #[pointee] T: ?Sized> {
+    data: &'a mut T,
+}
+
+#[pointee]
+fn f() {}
+
+#[derive(AnotherMacro)]
+#[pointee]
+struct MyStruct;
+
+fn main() {}
diff --git a/tests/ui/deriving/built-in-proc-macro-scope.stdout b/tests/ui/deriving/built-in-proc-macro-scope.stdout
new file mode 100644
index 0000000000000..c649b7a9a574c
--- /dev/null
+++ b/tests/ui/deriving/built-in-proc-macro-scope.stdout
@@ -0,0 +1,43 @@
+#![feature(prelude_import)]
+#![no_std]
+//@ check-pass
+//@ aux-build: another-proc-macro.rs
+//@ compile-flags: -Zunpretty=expanded
+
+#![feature(derive_smart_pointer)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+#[macro_use]
+extern crate another_proc_macro;
+
+use another_proc_macro::{pointee, AnotherMacro};
+
+#[repr(transparent)]
+pub struct Ptr<'a, #[pointee] T: ?Sized> {
+    data: &'a mut T,
+}
+#[automatically_derived]
+impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
+    ::core::ops::DispatchFromDyn<Ptr<'a, __S>> for Ptr<'a, T> {
+}
+#[automatically_derived]
+impl<'a, T: ?Sized + ::core::marker::Unsize<__S>, __S: ?Sized>
+    ::core::ops::CoerceUnsized<Ptr<'a, __S>> for Ptr<'a, T> {
+}
+
+
+
+const _: () =
+    {
+        const POINTEE_MACRO_ATTR_DERIVED: () = ();
+    };
+#[pointee]
+struct MyStruct;
+const _: () =
+    {
+        const ANOTHER_MACRO_DERIVED: () = ();
+    };
+fn main() {}
diff --git a/tests/ui/deriving/proc-macro-attribute-mixing.rs b/tests/ui/deriving/proc-macro-attribute-mixing.rs
new file mode 100644
index 0000000000000..489665ebeb520
--- /dev/null
+++ b/tests/ui/deriving/proc-macro-attribute-mixing.rs
@@ -0,0 +1,20 @@
+// This test certify that we can mix attribute macros from Rust and external proc-macros.
+// For instance, `#[derive(Default)]` uses `#[default]` and `#[derive(SmartPointer)]` uses
+// `#[pointee]`.
+// The scoping rule should allow the use of the said two attributes when external proc-macros
+// are in scope.
+
+//@ check-pass
+//@ aux-build: another-proc-macro.rs
+//@ compile-flags: -Zunpretty=expanded
+
+#![feature(derive_smart_pointer)]
+
+#[macro_use]
+extern crate another_proc_macro;
+
+#[pointee]
+fn f() {}
+
+#[default]
+fn g() {}
diff --git a/tests/ui/deriving/proc-macro-attribute-mixing.stdout b/tests/ui/deriving/proc-macro-attribute-mixing.stdout
new file mode 100644
index 0000000000000..f314f6efbe2b9
--- /dev/null
+++ b/tests/ui/deriving/proc-macro-attribute-mixing.stdout
@@ -0,0 +1,30 @@
+#![feature(prelude_import)]
+#![no_std]
+// This test certify that we can mix attribute macros from Rust and external proc-macros.
+// For instance, `#[derive(Default)]` uses `#[default]` and `#[derive(SmartPointer)]` uses
+// `#[pointee]`.
+// The scoping rule should allow the use of the said two attributes when external proc-macros
+// are in scope.
+
+//@ check-pass
+//@ aux-build: another-proc-macro.rs
+//@ compile-flags: -Zunpretty=expanded
+
+#![feature(derive_smart_pointer)]
+#[prelude_import]
+use ::std::prelude::rust_2015::*;
+#[macro_use]
+extern crate std;
+
+#[macro_use]
+extern crate another_proc_macro;
+
+
+const _: () =
+    {
+        const POINTEE_MACRO_ATTR_DERIVED: () = ();
+    };
+const _: () =
+    {
+        const DEFAULT_MACRO_ATTR_DERIVED: () = ();
+    };
diff --git a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs
index 3257a9ca624ba..7b4764ee768ab 100644
--- a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs
+++ b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.rs
@@ -3,7 +3,6 @@ use std::marker::SmartPointer; //~ ERROR use of unstable library feature 'derive
 #[derive(SmartPointer)] //~ ERROR use of unstable library feature 'derive_smart_pointer'
 #[repr(transparent)]
 struct MyPointer<'a, #[pointee] T: ?Sized> {
-    //~^ ERROR the `#[pointee]` attribute is an experimental feature
     ptr: &'a T,
 }
 
diff --git a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr
index 19501939dc5be..ea4d1271b7c87 100644
--- a/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr
+++ b/tests/ui/feature-gates/feature-gate-derive-smart-pointer.stderr
@@ -8,16 +8,6 @@ LL | #[derive(SmartPointer)]
    = help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error[E0658]: the `#[pointee]` attribute is an experimental feature
-  --> $DIR/feature-gate-derive-smart-pointer.rs:5:22
-   |
-LL | struct MyPointer<'a, #[pointee] T: ?Sized> {
-   |                      ^^^^^^^^^^
-   |
-   = note: see issue #123430 <https://github.com/rust-lang/rust/issues/123430> for more information
-   = help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable
-   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
-
 error[E0658]: use of unstable library feature 'derive_smart_pointer'
   --> $DIR/feature-gate-derive-smart-pointer.rs:1:5
    |
@@ -28,6 +18,6 @@ LL | use std::marker::SmartPointer;
    = help: add `#![feature(derive_smart_pointer)]` to the crate attributes to enable
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
-error: aborting due to 3 previous errors
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0658`.