syntax: Rename variants of SyntaxExtension
for consistency
This commit is contained in:
parent
0468eb63ad
commit
93eb63c9a5
12 changed files with 65 additions and 70 deletions
|
@ -614,7 +614,7 @@ impl<'a> CrateLoader<'a> {
|
|||
match decl {
|
||||
ProcMacro::CustomDerive { trait_name, attributes, client } => {
|
||||
let attrs = attributes.iter().cloned().map(Symbol::intern).collect::<Vec<_>>();
|
||||
(trait_name, SyntaxExtension::ProcMacroDerive(
|
||||
(trait_name, SyntaxExtension::Derive(
|
||||
Box::new(ProcMacroDerive {
|
||||
client,
|
||||
attrs: attrs.clone(),
|
||||
|
@ -624,13 +624,13 @@ impl<'a> CrateLoader<'a> {
|
|||
))
|
||||
}
|
||||
ProcMacro::Attr { name, client } => {
|
||||
(name, SyntaxExtension::AttrProcMacro(
|
||||
(name, SyntaxExtension::Attr(
|
||||
Box::new(AttrProcMacro { client }),
|
||||
root.edition,
|
||||
))
|
||||
}
|
||||
ProcMacro::Bang { name, client } => {
|
||||
(name, SyntaxExtension::ProcMacro {
|
||||
(name, SyntaxExtension::Bang {
|
||||
expander: Box::new(BangProcMacro { client }),
|
||||
allow_internal_unstable: None,
|
||||
edition: root.edition,
|
||||
|
|
|
@ -430,7 +430,7 @@ impl cstore::CStore {
|
|||
use syntax_ext::proc_macro_impl::BangProcMacro;
|
||||
|
||||
let client = proc_macro::bridge::client::Client::expand1(proc_macro::quote);
|
||||
let ext = SyntaxExtension::ProcMacro {
|
||||
let ext = SyntaxExtension::Bang {
|
||||
expander: Box::new(BangProcMacro { client }),
|
||||
allow_internal_unstable: Some(vec![sym::proc_macro_def_site].into()),
|
||||
edition: data.root.edition,
|
||||
|
|
|
@ -4,7 +4,7 @@ use rustc::lint::{EarlyLintPassObject, LateLintPassObject, LintId, Lint};
|
|||
use rustc::session::Session;
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
|
||||
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension, NormalTT};
|
||||
use syntax::ext::base::{SyntaxExtension, NamedSyntaxExtension};
|
||||
use syntax::ext::base::MacroExpanderFn;
|
||||
use syntax::ext::hygiene::Transparency;
|
||||
use syntax::symbol::{Symbol, sym};
|
||||
|
@ -89,7 +89,7 @@ impl<'a> Registry<'a> {
|
|||
if name == sym::macro_rules {
|
||||
panic!("user-defined macros may not be named `macro_rules`");
|
||||
}
|
||||
if let NormalTT { def_info: ref mut def_info @ None, .. } = extension {
|
||||
if let SyntaxExtension::LegacyBang { def_info: ref mut def_info @ None, .. } = extension {
|
||||
*def_info = Some((ast::CRATE_NODE_ID, self.krate_span));
|
||||
}
|
||||
self.syntax_exts.push((name, extension));
|
||||
|
@ -98,10 +98,10 @@ impl<'a> Registry<'a> {
|
|||
/// Register a macro of the usual kind.
|
||||
///
|
||||
/// This is a convenience wrapper for `register_syntax_extension`.
|
||||
/// It builds for you a `NormalTT` that calls `expander`,
|
||||
/// It builds for you a `SyntaxExtension::LegacyBang` that calls `expander`,
|
||||
/// and also takes care of interning the macro's name.
|
||||
pub fn register_macro(&mut self, name: &str, expander: MacroExpanderFn) {
|
||||
self.register_syntax_extension(Symbol::intern(name), NormalTT {
|
||||
self.register_syntax_extension(Symbol::intern(name), SyntaxExtension::LegacyBang {
|
||||
expander: Box::new(expander),
|
||||
def_info: None,
|
||||
transparency: Transparency::SemiTransparent,
|
||||
|
|
|
@ -242,7 +242,7 @@ impl<'a> base::Resolver for Resolver<'a> {
|
|||
fn check_unused_macros(&self) {
|
||||
for did in self.unused_macros.iter() {
|
||||
let id_span = match *self.macro_map[did] {
|
||||
SyntaxExtension::NormalTT { def_info, .. } => def_info,
|
||||
SyntaxExtension::LegacyBang { def_info, .. } => def_info,
|
||||
_ => None,
|
||||
};
|
||||
if let Some((id, span)) = id_span {
|
||||
|
@ -586,7 +586,7 @@ impl<'a> Resolver<'a> {
|
|||
match self.resolve_macro_to_res(derive, MacroKind::Derive,
|
||||
&parent_scope, true, force) {
|
||||
Ok((_, ext)) => {
|
||||
if let SyntaxExtension::ProcMacroDerive(_, helpers, _) = &*ext {
|
||||
if let SyntaxExtension::Derive(_, helpers, _) = &*ext {
|
||||
if helpers.contains(&ident.name) {
|
||||
let binding =
|
||||
(Res::NonMacroAttr(NonMacroAttrKind::DeriveHelper),
|
||||
|
|
|
@ -471,7 +471,7 @@ fn build_macro(cx: &DocContext<'_>, did: DefId, name: ast::Name) -> clean::ItemE
|
|||
}
|
||||
LoadedMacro::ProcMacro(ext) => {
|
||||
let helpers = match &*ext {
|
||||
&SyntaxExtension::ProcMacroDerive(_, ref syms, ..) => { syms.clean(cx) }
|
||||
&SyntaxExtension::Derive(_, ref syms, ..) => { syms.clean(cx) }
|
||||
_ => Vec::new(),
|
||||
};
|
||||
|
||||
|
|
|
@ -433,7 +433,7 @@ fn macro_resolve(cx: &DocContext<'_>, path_str: &str) -> Option<Res> {
|
|||
if let Res::Def(DefKind::Macro(MacroKind::ProcMacroStub), _) = res {
|
||||
// skip proc-macro stubs, they'll cause `get_macro` to crash
|
||||
} else {
|
||||
if let SyntaxExtension::NormalTT { .. } = *resolver.get_macro(res) {
|
||||
if let SyntaxExtension::LegacyBang { .. } = *resolver.get_macro(res) {
|
||||
return Some(res.map_id(|_| panic!("unexpected id")));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
pub use SyntaxExtension::*;
|
||||
|
||||
use crate::ast::{self, Attribute, Name, PatKind};
|
||||
use crate::attr::HasAttrs;
|
||||
use crate::source_map::{SourceMap, Spanned, respan};
|
||||
|
@ -553,7 +551,7 @@ impl MacroKind {
|
|||
/// An enum representing the different kinds of syntax extensions.
|
||||
pub enum SyntaxExtension {
|
||||
/// A token-based function-like macro.
|
||||
ProcMacro {
|
||||
Bang {
|
||||
/// An expander with signature TokenStream -> TokenStream.
|
||||
expander: Box<dyn ProcMacro + sync::Sync + sync::Send>,
|
||||
/// Whitelist of unstable features that are treated as stable inside this macro.
|
||||
|
@ -563,7 +561,7 @@ pub enum SyntaxExtension {
|
|||
},
|
||||
|
||||
/// An AST-based function-like macro.
|
||||
NormalTT {
|
||||
LegacyBang {
|
||||
/// An expander with signature TokenStream -> AST.
|
||||
expander: Box<dyn TTMacroExpander + sync::Sync + sync::Send>,
|
||||
/// Some info about the macro's definition point.
|
||||
|
@ -583,7 +581,7 @@ pub enum SyntaxExtension {
|
|||
},
|
||||
|
||||
/// A token-based attribute macro.
|
||||
AttrProcMacro(
|
||||
Attr(
|
||||
/// An expander with signature (TokenStream, TokenStream) -> TokenStream.
|
||||
/// The first TokenSteam is the attribute itself, the second is the annotated item.
|
||||
/// The produced TokenSteam replaces the input TokenSteam.
|
||||
|
@ -593,7 +591,7 @@ pub enum SyntaxExtension {
|
|||
),
|
||||
|
||||
/// An AST-based attribute macro.
|
||||
MultiModifier(
|
||||
LegacyAttr(
|
||||
/// An expander with signature (AST, AST) -> AST.
|
||||
/// The first AST fragment is the attribute itself, the second is the annotated item.
|
||||
/// The produced AST fragment replaces the input AST fragment.
|
||||
|
@ -608,7 +606,7 @@ pub enum SyntaxExtension {
|
|||
},
|
||||
|
||||
/// A token-based derive macro.
|
||||
ProcMacroDerive(
|
||||
Derive(
|
||||
/// An expander with signature TokenStream -> TokenStream (not yet).
|
||||
/// The produced TokenSteam is appended to the input TokenSteam.
|
||||
Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
|
||||
|
@ -619,7 +617,7 @@ pub enum SyntaxExtension {
|
|||
),
|
||||
|
||||
/// An AST-based derive macro.
|
||||
BuiltinDerive(
|
||||
LegacyDerive(
|
||||
/// An expander with signature AST -> AST.
|
||||
/// The produced AST fragment is appended to the input AST fragment.
|
||||
Box<dyn MultiItemModifier + sync::Sync + sync::Send>,
|
||||
|
@ -630,41 +628,38 @@ impl SyntaxExtension {
|
|||
/// Returns which kind of macro calls this syntax extension.
|
||||
pub fn kind(&self) -> MacroKind {
|
||||
match *self {
|
||||
SyntaxExtension::NormalTT { .. } |
|
||||
SyntaxExtension::ProcMacro { .. } =>
|
||||
MacroKind::Bang,
|
||||
SyntaxExtension::NonMacroAttr { .. } |
|
||||
SyntaxExtension::MultiModifier(..) |
|
||||
SyntaxExtension::AttrProcMacro(..) =>
|
||||
MacroKind::Attr,
|
||||
SyntaxExtension::ProcMacroDerive(..) |
|
||||
SyntaxExtension::BuiltinDerive(..) =>
|
||||
MacroKind::Derive,
|
||||
SyntaxExtension::Bang { .. } |
|
||||
SyntaxExtension::LegacyBang { .. } => MacroKind::Bang,
|
||||
SyntaxExtension::Attr(..) |
|
||||
SyntaxExtension::LegacyAttr(..) |
|
||||
SyntaxExtension::NonMacroAttr { .. } => MacroKind::Attr,
|
||||
SyntaxExtension::Derive(..) |
|
||||
SyntaxExtension::LegacyDerive(..) => MacroKind::Derive,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn default_transparency(&self) -> Transparency {
|
||||
match *self {
|
||||
SyntaxExtension::NormalTT { transparency, .. } => transparency,
|
||||
SyntaxExtension::ProcMacro { .. } |
|
||||
SyntaxExtension::AttrProcMacro(..) |
|
||||
SyntaxExtension::ProcMacroDerive(..) |
|
||||
SyntaxExtension::LegacyBang { transparency, .. } => transparency,
|
||||
SyntaxExtension::Bang { .. } |
|
||||
SyntaxExtension::Attr(..) |
|
||||
SyntaxExtension::Derive(..) |
|
||||
SyntaxExtension::NonMacroAttr { .. } => Transparency::Opaque,
|
||||
SyntaxExtension::MultiModifier(..) |
|
||||
SyntaxExtension::BuiltinDerive(..) => Transparency::SemiTransparent,
|
||||
SyntaxExtension::LegacyAttr(..) |
|
||||
SyntaxExtension::LegacyDerive(..) => Transparency::SemiTransparent,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn edition(&self, default_edition: Edition) -> Edition {
|
||||
match *self {
|
||||
SyntaxExtension::NormalTT { edition, .. } |
|
||||
SyntaxExtension::ProcMacro { edition, .. } |
|
||||
SyntaxExtension::AttrProcMacro(.., edition) |
|
||||
SyntaxExtension::ProcMacroDerive(.., edition) => edition,
|
||||
SyntaxExtension::Bang { edition, .. } |
|
||||
SyntaxExtension::LegacyBang { edition, .. } |
|
||||
SyntaxExtension::Attr(.., edition) |
|
||||
SyntaxExtension::Derive(.., edition) => edition,
|
||||
// Unstable legacy stuff
|
||||
SyntaxExtension::NonMacroAttr { .. } |
|
||||
SyntaxExtension::MultiModifier(..) |
|
||||
SyntaxExtension::BuiltinDerive(..) => default_edition,
|
||||
SyntaxExtension::LegacyAttr(..) |
|
||||
SyntaxExtension::LegacyDerive(..) => default_edition,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -389,7 +389,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
let item = match self.cx.resolver.resolve_macro_path(
|
||||
path, MacroKind::Derive, Mark::root(), Vec::new(), false) {
|
||||
Ok(ext) => match *ext {
|
||||
BuiltinDerive(..) => item_with_markers.clone(),
|
||||
SyntaxExtension::LegacyDerive(..) => item_with_markers.clone(),
|
||||
_ => item.clone(),
|
||||
},
|
||||
_ => item.clone(),
|
||||
|
@ -548,7 +548,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
_ => unreachable!(),
|
||||
};
|
||||
|
||||
if let NonMacroAttr { mark_used: false } = *ext {} else {
|
||||
if let SyntaxExtension::NonMacroAttr { mark_used: false } = *ext {} else {
|
||||
// Macro attrs are always used when expanded,
|
||||
// non-macro attrs are considered used when the field says so.
|
||||
attr::mark_used(&attr);
|
||||
|
@ -564,18 +564,18 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
});
|
||||
|
||||
match *ext {
|
||||
NonMacroAttr { .. } => {
|
||||
SyntaxExtension::NonMacroAttr { .. } => {
|
||||
attr::mark_known(&attr);
|
||||
item.visit_attrs(|attrs| attrs.push(attr));
|
||||
Some(invoc.fragment_kind.expect_from_annotatables(iter::once(item)))
|
||||
}
|
||||
MultiModifier(ref mac) => {
|
||||
SyntaxExtension::LegacyAttr(ref mac) => {
|
||||
let meta = attr.parse_meta(self.cx.parse_sess)
|
||||
.map_err(|mut e| { e.emit(); }).ok()?;
|
||||
let item = mac.expand(self.cx, attr.span, &meta, item);
|
||||
Some(invoc.fragment_kind.expect_from_annotatables(item))
|
||||
}
|
||||
AttrProcMacro(ref mac, ..) => {
|
||||
SyntaxExtension::Attr(ref mac, ..) => {
|
||||
self.gate_proc_macro_attr_item(attr.span, &item);
|
||||
let item_tok = TokenTree::token(token::Interpolated(Lrc::new(match item {
|
||||
Annotatable::Item(item) => token::NtItem(item),
|
||||
|
@ -592,7 +592,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
self.gate_proc_macro_expansion(attr.span, &res);
|
||||
res
|
||||
}
|
||||
ProcMacroDerive(..) | BuiltinDerive(..) => {
|
||||
SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => {
|
||||
self.cx.span_err(attr.span, &format!("`{}` is a derive macro", attr.path));
|
||||
self.cx.trace_macros_diag();
|
||||
invoc.fragment_kind.dummy(attr.span)
|
||||
|
@ -747,7 +747,7 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
};
|
||||
|
||||
let opt_expanded = match *ext {
|
||||
NormalTT {
|
||||
SyntaxExtension::LegacyBang {
|
||||
ref expander,
|
||||
def_info,
|
||||
ref allow_internal_unstable,
|
||||
|
@ -774,20 +774,22 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
}
|
||||
}
|
||||
|
||||
MultiModifier(..) | AttrProcMacro(..) | SyntaxExtension::NonMacroAttr { .. } => {
|
||||
SyntaxExtension::Attr(..) |
|
||||
SyntaxExtension::LegacyAttr(..) |
|
||||
SyntaxExtension::NonMacroAttr { .. } => {
|
||||
self.cx.span_err(path.span,
|
||||
&format!("`{}` can only be used in attributes", path));
|
||||
self.cx.trace_macros_diag();
|
||||
kind.dummy(span)
|
||||
}
|
||||
|
||||
ProcMacroDerive(..) | BuiltinDerive(..) => {
|
||||
SyntaxExtension::Derive(..) | SyntaxExtension::LegacyDerive(..) => {
|
||||
self.cx.span_err(path.span, &format!("`{}` is a derive macro", path));
|
||||
self.cx.trace_macros_diag();
|
||||
kind.dummy(span)
|
||||
}
|
||||
|
||||
SyntaxExtension::ProcMacro { ref expander, ref allow_internal_unstable, edition } => {
|
||||
SyntaxExtension::Bang { ref expander, ref allow_internal_unstable, edition } => {
|
||||
if ident.name != kw::Invalid {
|
||||
let msg =
|
||||
format!("macro {}! expects no ident argument, given '{}'", path, ident);
|
||||
|
@ -885,9 +887,9 @@ impl<'a, 'b> MacroExpander<'a, 'b> {
|
|||
};
|
||||
|
||||
match ext {
|
||||
ProcMacroDerive(expander, ..) | BuiltinDerive(expander) => {
|
||||
SyntaxExtension::Derive(expander, ..) | SyntaxExtension::LegacyDerive(expander) => {
|
||||
let meta = match ext {
|
||||
ProcMacroDerive(..) => ast::MetaItem { // FIXME(jseyfried) avoid this
|
||||
SyntaxExtension::Derive(..) => ast::MetaItem { // FIXME(jseyfried) avoid this
|
||||
path: Path::from_ident(Ident::invalid()),
|
||||
span: DUMMY_SP,
|
||||
node: ast::MetaItemKind::Word,
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
use crate::{ast, attr};
|
||||
use crate::edition::Edition;
|
||||
use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension};
|
||||
use crate::ext::base::{NormalTT, TTMacroExpander};
|
||||
use crate::ext::base::{DummyResult, ExtCtxt, MacResult, SyntaxExtension, TTMacroExpander};
|
||||
use crate::ext::expand::{AstFragment, AstFragmentKind};
|
||||
use crate::ext::hygiene::Transparency;
|
||||
use crate::ext::tt::macro_parser::{Success, Error, Failure};
|
||||
|
@ -425,7 +424,7 @@ pub fn compile(
|
|||
}
|
||||
});
|
||||
|
||||
NormalTT {
|
||||
SyntaxExtension::LegacyBang {
|
||||
expander,
|
||||
def_info: Some((def.id, def.span)),
|
||||
transparency,
|
||||
|
|
|
@ -71,7 +71,7 @@ macro_rules! derive_traits {
|
|||
$(
|
||||
resolver.add_builtin(
|
||||
ast::Ident::with_empty_ctxt(Symbol::intern($name)),
|
||||
Lrc::new(SyntaxExtension::BuiltinDerive(Box::new(BuiltinDerive($func))))
|
||||
Lrc::new(SyntaxExtension::LegacyDerive(Box::new(BuiltinDerive($func))))
|
||||
);
|
||||
)*
|
||||
}
|
||||
|
|
|
@ -41,7 +41,8 @@ pub mod proc_macro_impl;
|
|||
|
||||
use rustc_data_structures::sync::Lrc;
|
||||
use syntax::ast;
|
||||
use syntax::ext::base::{MacroExpanderFn, NormalTT, NamedSyntaxExtension, MultiModifier};
|
||||
|
||||
use syntax::ext::base::{MacroExpanderFn, NamedSyntaxExtension, SyntaxExtension};
|
||||
use syntax::ext::hygiene::Transparency;
|
||||
use syntax::edition::Edition;
|
||||
use syntax::symbol::{sym, Symbol};
|
||||
|
@ -57,7 +58,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
|||
macro_rules! register {
|
||||
($( $name:ident: $f:expr, )*) => { $(
|
||||
register(Symbol::intern(stringify!($name)),
|
||||
NormalTT {
|
||||
SyntaxExtension::LegacyBang {
|
||||
expander: Box::new($f as MacroExpanderFn),
|
||||
def_info: None,
|
||||
transparency: Transparency::SemiTransparent,
|
||||
|
@ -95,13 +96,13 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
|||
assert: assert::expand_assert,
|
||||
}
|
||||
|
||||
register(sym::test_case, MultiModifier(Box::new(test_case::expand)));
|
||||
register(sym::test, MultiModifier(Box::new(test::expand_test)));
|
||||
register(sym::bench, MultiModifier(Box::new(test::expand_bench)));
|
||||
register(sym::test_case, SyntaxExtension::LegacyAttr(Box::new(test_case::expand)));
|
||||
register(sym::test, SyntaxExtension::LegacyAttr(Box::new(test::expand_test)));
|
||||
register(sym::bench, SyntaxExtension::LegacyAttr(Box::new(test::expand_bench)));
|
||||
|
||||
// format_args uses `unstable` things internally.
|
||||
register(Symbol::intern("format_args"),
|
||||
NormalTT {
|
||||
SyntaxExtension::LegacyBang {
|
||||
expander: Box::new(format::expand_format_args),
|
||||
def_info: None,
|
||||
transparency: Transparency::SemiTransparent,
|
||||
|
@ -112,7 +113,7 @@ pub fn register_builtins(resolver: &mut dyn syntax::ext::base::Resolver,
|
|||
edition,
|
||||
});
|
||||
register(sym::format_args_nl,
|
||||
NormalTT {
|
||||
SyntaxExtension::LegacyBang {
|
||||
expander: Box::new(format::expand_format_args_nl),
|
||||
def_info: None,
|
||||
transparency: Transparency::SemiTransparent,
|
||||
|
|
|
@ -10,12 +10,10 @@ extern crate rustc_plugin;
|
|||
|
||||
use std::borrow::ToOwned;
|
||||
use syntax::ast;
|
||||
use syntax::ext::hygiene;
|
||||
use syntax::ext::build::AstBuilder;
|
||||
use syntax::ext::base::{TTMacroExpander, ExtCtxt, MacResult, MacEager, NormalTT};
|
||||
use syntax::ext::base::{SyntaxExtension, TTMacroExpander, ExtCtxt, MacResult, MacEager};
|
||||
use syntax::ext::hygiene::Transparency;
|
||||
use syntax::print::pprust;
|
||||
use syntax::ptr::P;
|
||||
use syntax::symbol::Symbol;
|
||||
use syntax_pos::Span;
|
||||
use syntax::tokenstream::TokenStream;
|
||||
|
@ -30,7 +28,7 @@ impl TTMacroExpander for Expander {
|
|||
ecx: &'cx mut ExtCtxt,
|
||||
sp: Span,
|
||||
_: TokenStream,
|
||||
_: Option<Span>) -> Box<MacResult+'cx> {
|
||||
_: Option<Span>) -> Box<dyn MacResult+'cx> {
|
||||
let args = self.args.iter().map(|i| pprust::meta_list_item_to_string(i))
|
||||
.collect::<Vec<_>>().join(", ");
|
||||
MacEager::expr(ecx.expr_str(sp, Symbol::intern(&args)))
|
||||
|
@ -41,7 +39,7 @@ impl TTMacroExpander for Expander {
|
|||
pub fn plugin_registrar(reg: &mut Registry) {
|
||||
let args = reg.args().to_owned();
|
||||
reg.register_syntax_extension(Symbol::intern("plugin_args"),
|
||||
NormalTT {
|
||||
SyntaxExtension::LegacyBang {
|
||||
expander: Box::new(Expander { args: args, }),
|
||||
def_info: None,
|
||||
transparency: Transparency::SemiTransparent,
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue